mirror of
https://github.com/vdukhovni/postfix
synced 2025-08-22 09:57:34 +00:00
postfix-3.10-20241024
This commit is contained in:
parent
a5b1b93841
commit
c7a9de81bf
@ -28394,3 +28394,48 @@ Apologies for any names omitted.
|
|||||||
util/stream_recv_fd.c, util/stream_test.c,
|
util/stream_recv_fd.c, util/stream_test.c,
|
||||||
util/unix_dgram_connect.c, util/unix_dgram_listen.c,
|
util/unix_dgram_connect.c, util/unix_dgram_listen.c,
|
||||||
util/vbuf.c.
|
util/vbuf.c.
|
||||||
|
|
||||||
|
20241015
|
||||||
|
|
||||||
|
Documentation: updated the TLSRPT_README text and example
|
||||||
|
for section "Delivering TLSRPT summaries via email". File:
|
||||||
|
proto/TLSRPT_README.html.
|
||||||
|
|
||||||
|
20241021
|
||||||
|
|
||||||
|
Bugfix (defect introduced: postfix 3.0): the default master.cf
|
||||||
|
syslog_name setting for the relay service did not preserve
|
||||||
|
multi-instance information. File: conf/master.cf.
|
||||||
|
|
||||||
|
20241022
|
||||||
|
|
||||||
|
Documentation: updated the TLSRPT_README examples for
|
||||||
|
MTA-STS. File: proto/TLSRPT_README.html.
|
||||||
|
|
||||||
|
Documentation: add explicit guidance to use "postconf -x"
|
||||||
|
when checking an inline pcre or regexp table for unescaped
|
||||||
|
'$' characters. Files: mantools/postlink, proto/pcre_table,
|
||||||
|
proto/regexp_table.
|
||||||
|
|
||||||
|
Documentation: be explicit about when Postfix expands $name
|
||||||
|
in inline pcre, regexp, and cidr lookup tables. Files:
|
||||||
|
proto/cidr_table, proto/pcre_table, proto/regexp_table.
|
||||||
|
|
||||||
|
Safety: replace ASCII control characters that match isspace()
|
||||||
|
with space characters. This prevents line breaks etc. in
|
||||||
|
smtp_tls_policy attribute values that use the long form "{
|
||||||
|
name = value }". This form was introduced with Postfix 3.10
|
||||||
|
TLSRPT support. Files: smtp/smtp_tls_policy.c, util/extpar.c,
|
||||||
|
util/Makefile.in, util/normalize_ws.c, util/stringops.h.
|
||||||
|
|
||||||
|
20241023
|
||||||
|
|
||||||
|
Logging: Postfix SMTP server 'reject' logging now shows the
|
||||||
|
sasl_method, sasl_username, and sasl_sender if available.
|
||||||
|
Viktor Dukhovni. Files: smtpd/smtpd_check.c.
|
||||||
|
|
||||||
|
20241024
|
||||||
|
|
||||||
|
Documentation: in a pgsql: client configuration, the setting
|
||||||
|
"dbname" is required, but ignored when the setting "hosts"
|
||||||
|
contains an URI with a database name. File: proto/pgsql_table.
|
||||||
|
@ -175,37 +175,39 @@ Notes:
|
|||||||
|
|
||||||
DDeelliivveerriinngg TTLLSSRRPPTT ssuummmmaarriieess vviiaa eemmaaiill
|
DDeelliivveerriinngg TTLLSSRRPPTT ssuummmmaarriieess vviiaa eemmaaiill
|
||||||
|
|
||||||
RFC 8460 suggests not to enforce strict TLS security when sending daily
|
RFC 8460 Section 3 specifies that an MTA must not enforce TLS security when
|
||||||
success/failure summaries via email, to avoid delivery delays caused by a
|
sending failure reports via email. However, Postfix currently has no way to
|
||||||
failure to enforce TLS security. Postfix currently does not have a mechanism to
|
request that TLS enforcement will be disabled when submitting an email message.
|
||||||
disable TLS security enforcement when submitting an email message; this section
|
|
||||||
provides a workaround.
|
|
||||||
|
|
||||||
By design, TLSRPT is not a real-time notification system; it takes on average
|
Options:
|
||||||
12 hours before a failure is reported in a daily success/failure summary. If a
|
|
||||||
TLS-related delay of a day or more is undesirable, one could set up a transport
|
* Do nothing. When TLS security enforcement is required, a persistent
|
||||||
map to make TLS security optional for specific TLSRPT email notification email
|
enforcement failure will delay the delivery of a TLSRPT summary until the
|
||||||
addresses.
|
problem is addressed, or until the message expires in the mail queue. Keep
|
||||||
|
in mind that TLSRPT is not a real-time monitoring service; it takes on
|
||||||
|
average 12 hours before a failure is reported through TLSRPT.
|
||||||
|
|
||||||
|
* Exclude the sender of TLSRPT summaries from TLS enforcement. Implement the
|
||||||
|
configuration below on outbound MTA instances (replace noreply-smtp-tls-
|
||||||
|
reporting@example.com with your actual report generator's sender address):
|
||||||
|
|
||||||
/etc/postfix/main.cf:
|
/etc/postfix/main.cf:
|
||||||
transport_maps = hash:/etc/postfix/transport
|
# Limitation: this setting is overruled with transport_maps.
|
||||||
|
sender_dependent_default_transport_maps = inline:{
|
||||||
/etc/postfix/transport:
|
{ noreply-smtp-tls-reporting@example.com = allow-plaintext } }
|
||||||
smtp-tls-report@example.com allow-plaintext:
|
|
||||||
...
|
|
||||||
|
|
||||||
/etc/postfix/master.cf:
|
/etc/postfix/master.cf:
|
||||||
# service name type private unpriv chroot wakeup maxproc
|
# service name type private unpriv chroot wakeup maxproc
|
||||||
command
|
command
|
||||||
allow-plaintext unix - - n - - smtp
|
allow-plaintext unix - - n - - smtp
|
||||||
-o smtp_tls_security_level=may
|
-o { smtp_tls_security_level = may }
|
||||||
-o smtp_tls_policy_maps=static:may
|
-o { smtp_tls_policy_maps = static:may }
|
||||||
|
|
||||||
MMTTAA--SSTTSS SSuuppppoorrtt vviiaa ssmmttpp__ttllss__ppoolliiccyy__mmaappss
|
MMTTAA--SSTTSS SSuuppppoorrtt vviiaa ssmmttpp__ttllss__ppoolliiccyy__mmaappss
|
||||||
|
|
||||||
Postfix supports MTA-STS though an smtp_tls_policy_maps policy plugin. Postfix
|
Postfix supports MTA-STS though an smtp_tls_policy_maps policy plugin, which
|
||||||
3.10 and later expect a policy response with the usual security level and
|
replies with a TLS security level and optional matching requirements. Postfix
|
||||||
matching requirements, plus any applicable name=value attributes described
|
3.10 and later optionally also accept the name=value attributes described
|
||||||
below. Specify { name = value } when a value may contain whitespace.
|
below. Specify { name = value } when a value may contain whitespace.
|
||||||
|
|
||||||
Note 1: Postfix 3.10 and later will accept these attributes in an MTA-STS
|
Note 1: Postfix 3.10 and later will accept these attributes in an MTA-STS
|
||||||
@ -215,8 +217,17 @@ below. Specify { name = value } when a value may contain whitespace.
|
|||||||
|
|
||||||
Note 2: It is an error to specify these attributes for a non-STS policy.
|
Note 2: It is an error to specify these attributes for a non-STS policy.
|
||||||
|
|
||||||
The examples in the table apply to the MTA-STS policy example given in https://
|
The examples in the table apply to the MTA-STS policy example given in RFC 8461
|
||||||
datatracker.ietf.org/doc/html/rfc8460#section-4.5.
|
Section 3.2:
|
||||||
|
|
||||||
|
version: STSv1
|
||||||
|
mode: enforce
|
||||||
|
mx: mail.example.com
|
||||||
|
mx: *.example.net
|
||||||
|
mx: backupmx.example.com
|
||||||
|
max_age: 604800
|
||||||
|
|
||||||
|
A policy response may contain line breaks.
|
||||||
|
|
||||||
* policy_type=type
|
* policy_type=type
|
||||||
|
|
||||||
@ -238,7 +249,7 @@ datatracker.ietf.org/doc/html/rfc8460#section-4.5.
|
|||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
|
||||||
{ policy_string = version: STSv1 } { policy_string = mode: testing }
|
{ policy_string = version: STSv1 } { policy_string = mode: enforce }
|
||||||
...
|
...
|
||||||
|
|
||||||
This form ignores whitespace after the opening "{", around the "=", and
|
This form ignores whitespace after the opening "{", around the "=", and
|
||||||
@ -251,7 +262,7 @@ datatracker.ietf.org/doc/html/rfc8460#section-4.5.
|
|||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
|
||||||
mx_host_pattern=mx1.example.com mx_host_pattern=mx2.example.com ...
|
mx_host_pattern=mail.example.com mx_host_pattern=*.example.net ...
|
||||||
|
|
||||||
* policy_failure=type
|
* policy_failure=type
|
||||||
|
|
||||||
|
@ -6,6 +6,19 @@ Wish list:
|
|||||||
|
|
||||||
Disable -DSNAPSHOT and -DNONPROD in makedefs.
|
Disable -DSNAPSHOT and -DNONPROD in makedefs.
|
||||||
|
|
||||||
|
Add a mail_version chek to each pluggable database client.
|
||||||
|
|
||||||
|
Add an option for a built-in JSON generator. This would
|
||||||
|
simplify TLSRPT adoption by eliminating a build-time and
|
||||||
|
run-time dependency on the libtlsrpt client library. Prior
|
||||||
|
art: this approach was previously used to implement Postfix
|
||||||
|
Milter support.
|
||||||
|
|
||||||
|
Make TLSRPT support pluggable (postfix-tlsrpt.so, like
|
||||||
|
postfix-ldap.so, postfix-mysql.so and so on). This avods a
|
||||||
|
hard install-time dependency on sys4 libtlsrpt. The sys4
|
||||||
|
code would still be a build-time dependency.
|
||||||
|
|
||||||
Add smtp_tlsrpt_allow_list feature (default: static:all) to limit
|
Add smtp_tlsrpt_allow_list feature (default: static:all) to limit
|
||||||
the domains for which Postfix generates TLSRPT daily summaries.
|
the domains for which Postfix generates TLSRPT daily summaries.
|
||||||
|
|
||||||
@ -13,6 +26,8 @@ Wish list:
|
|||||||
|
|
||||||
Add unit tests for smtp_tlsrpt.c, tlstrpd_wrapper.c, ...
|
Add unit tests for smtp_tlsrpt.c, tlstrpd_wrapper.c, ...
|
||||||
|
|
||||||
|
Add unit test for extpar.c
|
||||||
|
|
||||||
Add tests for Message-ID extraction in the cleanup daemon.
|
Add tests for Message-ID extraction in the cleanup daemon.
|
||||||
|
|
||||||
When debug logging is enabled, dict_db_open() logs a newline
|
When debug logging is enabled, dict_db_open() logs a newline
|
||||||
|
@ -69,7 +69,7 @@ proxymap unix - - n - - proxymap
|
|||||||
proxywrite unix - - n - 1 proxymap
|
proxywrite unix - - n - 1 proxymap
|
||||||
smtp unix - - n - - smtp
|
smtp unix - - n - - smtp
|
||||||
relay unix - - n - - smtp
|
relay unix - - n - - smtp
|
||||||
-o syslog_name=postfix/$service_name
|
-o syslog_name=${multi_instance_name?{$multi_instance_name}:{postfix}}/$service_name
|
||||||
# -o smtp_helo_timeout=5 -o smtp_connect_timeout=5
|
# -o smtp_helo_timeout=5 -o smtp_connect_timeout=5
|
||||||
showq unix n - n - - showq
|
showq unix n - n - - showq
|
||||||
error unix - - n - - error
|
error unix - - n - - error
|
||||||
|
@ -266,44 +266,51 @@ have the details for why TLS authentication failed. </p>
|
|||||||
|
|
||||||
<h2> <a name="delivering"> Delivering TLSRPT summaries via email</a> </h2>
|
<h2> <a name="delivering"> Delivering TLSRPT summaries via email</a> </h2>
|
||||||
|
|
||||||
<p> <a href="https://tools.ietf.org/html/rfc8460">RFC 8460</a> suggests not to enforce strict TLS security when sending
|
<p> <a href="https://datatracker.ietf.org/doc/html/rfc8460#section-3">RFC
|
||||||
daily success/failure summaries via email, to avoid delivery delays
|
8460 Section 3</a> specifies that an MTA must not enforce TLS
|
||||||
caused by a failure to enforce TLS security. Postfix currently does
|
security when sending failure reports via email. However, Postfix
|
||||||
not have a mechanism to disable TLS security enforcement when
|
currently has no way to request that TLS enforcement will be disabled
|
||||||
submitting an email message; this section provides a workaround. </p>
|
when submitting an email message. </p>
|
||||||
|
|
||||||
<p> By design, TLSRPT is not a real-time notification system; it
|
<p> Options:
|
||||||
takes on average 12 hours before a failure is reported in a daily
|
|
||||||
success/failure summary. If a TLS-related delay of a day or more
|
<ul>
|
||||||
is undesirable, one could set up a transport map to make TLS security
|
|
||||||
optional for specific TLSRPT email notification email addresses.
|
<li> <p> Do nothing. When TLS security enforcement is required, a
|
||||||
</p>
|
persistent enforcement failure will delay the delivery of a TLSRPT
|
||||||
|
summary until the problem is addressed, or until the message expires
|
||||||
|
in the mail queue. Keep in mind that TLSRPT is not a real-time
|
||||||
|
monitoring service; it takes on average 12 hours before a failure
|
||||||
|
is reported through TLSRPT. </p>
|
||||||
|
|
||||||
|
<li> <p> Exclude the sender of TLSRPT summaries from TLS enforcement.
|
||||||
|
Implement the configuration below on outbound MTA instances (replace
|
||||||
|
noreply-smtp-tls-reporting@example.com with your actual report
|
||||||
|
generator's sender address): </p>
|
||||||
|
|
||||||
<blockquote>
|
|
||||||
<pre>
|
<pre>
|
||||||
/etc/postfix/<a href="postconf.5.html">main.cf</a>:
|
/etc/postfix/<a href="postconf.5.html">main.cf</a>:
|
||||||
<a href="postconf.5.html#transport_maps">transport_maps</a> = <a href="DATABASE_README.html#types">hash</a>:/etc/postfix/transport
|
# Limitation: this setting is overruled with <a href="postconf.5.html#transport_maps">transport_maps</a>.
|
||||||
 
|
<a href="postconf.5.html#sender_dependent_default_transport_maps">sender_dependent_default_transport_maps</a> = <a href="DATABASE_README.html#types">inline</a>:{
|
||||||
/etc/postfix/transport:
|
{ noreply-smtp-tls-reporting@example.com = allow-plaintext } }
|
||||||
smtp-tls-report@example.com allow-plaintext:
|
|
||||||
...
|
|
||||||
 
|
 
|
||||||
/etc/postfix/<a href="master.5.html">master.cf</a>:
|
/etc/postfix/<a href="master.5.html">master.cf</a>:
|
||||||
# service name type private unpriv chroot wakeup maxproc command
|
# service name type private unpriv chroot wakeup maxproc command
|
||||||
allow-plaintext unix - - n - - smtp
|
allow-plaintext unix - - n - - smtp
|
||||||
-o <a href="postconf.5.html#smtp_tls_security_level">smtp_tls_security_level</a>=may
|
-o { <a href="postconf.5.html#smtp_tls_security_level">smtp_tls_security_level</a> = may }
|
||||||
-o <a href="postconf.5.html#smtp_tls_policy_maps">smtp_tls_policy_maps</a>=<a href="DATABASE_README.html#types">static</a>:may
|
-o { <a href="postconf.5.html#smtp_tls_policy_maps">smtp_tls_policy_maps</a> = <a href="DATABASE_README.html#types">static</a>:may }
|
||||||
</pre>
|
</pre>
|
||||||
</blockquote>
|
|
||||||
|
</ul>
|
||||||
|
|
||||||
<h2> <a name="mta-sts"> MTA-STS Support via smtp_tls_policy_maps
|
<h2> <a name="mta-sts"> MTA-STS Support via smtp_tls_policy_maps
|
||||||
</a></h2>
|
</a></h2>
|
||||||
|
|
||||||
<p> Postfix supports MTA-STS though an <a href="postconf.5.html#smtp_tls_policy_maps">smtp_tls_policy_maps</a>
|
<p> Postfix supports MTA-STS though an <a href="postconf.5.html#smtp_tls_policy_maps">smtp_tls_policy_maps</a> policy
|
||||||
policy plugin. Postfix 3.10 and later expect a policy response with
|
plugin, which replies with a TLS security level and optional matching
|
||||||
the usual security level and matching requirements, plus any
|
requirements. Postfix 3.10 and later optionally also accept the
|
||||||
applicable name=value attributes described below. Specify <tt>{
|
name=value attributes described below. Specify <tt>{ name = value
|
||||||
name = value }</tt> when a value may contain whitespace. </p>
|
}</tt> when a value may contain whitespace. </p>
|
||||||
|
|
||||||
<blockquote>
|
<blockquote>
|
||||||
|
|
||||||
@ -319,8 +326,22 @@ policy. </p>
|
|||||||
</blockquote>
|
</blockquote>
|
||||||
|
|
||||||
<p> The examples in the table apply to the MTA-STS policy example
|
<p> The examples in the table apply to the MTA-STS policy example
|
||||||
given in <a href="https://datatracker.ietf.org/doc/html/rfc8460#section-4.5">https://datatracker.ietf.org/doc/html/rfc8460#section-4.5</a>.
|
given in <a
|
||||||
<p>
|
href="https://datatracker.ietf.org/doc/html/rfc8461#section-3.2">
|
||||||
|
RFC 8461 Section 3.2</a>: </p>
|
||||||
|
|
||||||
|
<blockquote>
|
||||||
|
<pre>
|
||||||
|
version: STSv1
|
||||||
|
mode: enforce
|
||||||
|
mx: mail.example.com
|
||||||
|
mx: *.example.net
|
||||||
|
mx: backupmx.example.com
|
||||||
|
max_age: 604800
|
||||||
|
</pre>
|
||||||
|
</blockquote>
|
||||||
|
|
||||||
|
<p> A policy response may contain line breaks. </p>
|
||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
|
|
||||||
@ -347,7 +368,7 @@ in attribute values. </p>
|
|||||||
|
|
||||||
<blockquote>
|
<blockquote>
|
||||||
<pre>
|
<pre>
|
||||||
{ policy_string = version: STSv1 } { policy_string = mode: testing } ...
|
{ policy_string = version: STSv1 } { policy_string = mode: enforce } ...
|
||||||
</pre>
|
</pre>
|
||||||
</blockquote>
|
</blockquote>
|
||||||
|
|
||||||
@ -363,7 +384,7 @@ in the MTA-STS policy. </p>
|
|||||||
|
|
||||||
<blockquote>
|
<blockquote>
|
||||||
<pre>
|
<pre>
|
||||||
mx_host_pattern=mx1.example.com mx_host_pattern=mx2.example.com ...
|
mx_host_pattern=mail.example.com mx_host_pattern=*.example.net ...
|
||||||
</pre>
|
</pre>
|
||||||
</blockquote>
|
</blockquote>
|
||||||
</li>
|
</li>
|
||||||
|
@ -109,8 +109,9 @@ CIDR_TABLE(5) CIDR_TABLE(5)
|
|||||||
<a href="master.5.html">master.cf</a>:
|
<a href="master.5.html">master.cf</a>:
|
||||||
<b>.. -o {</b> <i>parameter</i> <b>= .. <a href="cidr_table.5.html">cidr</a>:{ {</b> <i>rule-1</i> <b>}, {</b> <i>rule-2</i> <b>} .. } .. } ..</b>
|
<b>.. -o {</b> <i>parameter</i> <b>= .. <a href="cidr_table.5.html">cidr</a>:{ {</b> <i>rule-1</i> <b>}, {</b> <i>rule-2</i> <b>} .. } .. } ..</b>
|
||||||
|
|
||||||
Postfix ignores whitespace after '{' and before '}', and writes each
|
Postfix recursively expands any <i>$parametername</i> instances in the above
|
||||||
<i>rule</i> as one text line to an in-memory file:
|
parameter value, ignores whitespace after '{' and before '}', and
|
||||||
|
writes each <i>rule</i> as one text line to an in-memory file:
|
||||||
|
|
||||||
in-memory file:
|
in-memory file:
|
||||||
rule-1
|
rule-1
|
||||||
@ -119,7 +120,7 @@ CIDR_TABLE(5) CIDR_TABLE(5)
|
|||||||
|
|
||||||
Postfix parses the result as if it is a file in /etc/postfix.
|
Postfix parses the result as if it is a file in /etc/postfix.
|
||||||
|
|
||||||
Note: if a rule contains <b>$</b>, specify <b>$$</b> to keep Postfix from trying to
|
Note: if a rule contains <b>$</b>, specify <b>$$</b> to keep Postfix from trying to
|
||||||
do <i>$name</i> expansion as it evaluates a parameter value.
|
do <i>$name</i> expansion as it evaluates a parameter value.
|
||||||
|
|
||||||
<b><a name="example_smtpd_access_map">EXAMPLE SMTPD ACCESS MAP</a></b>
|
<b><a name="example_smtpd_access_map">EXAMPLE SMTPD ACCESS MAP</a></b>
|
||||||
|
@ -181,8 +181,9 @@ PCRE_TABLE(5) PCRE_TABLE(5)
|
|||||||
<a href="master.5.html">master.cf</a>:
|
<a href="master.5.html">master.cf</a>:
|
||||||
<b>.. -o {</b> <i>parameter</i> <b>= .. <a href="pcre_table.5.html">pcre</a>:{ {</b> <i>rule-1</i> <b>}, {</b> <i>rule-2</i> <b>} .. } .. } ..</b>
|
<b>.. -o {</b> <i>parameter</i> <b>= .. <a href="pcre_table.5.html">pcre</a>:{ {</b> <i>rule-1</i> <b>}, {</b> <i>rule-2</i> <b>} .. } .. } ..</b>
|
||||||
|
|
||||||
Postfix ignores whitespace after '{' and before '}', and writes each
|
Postfix recursively expands any <i>$parametername</i> instances in the above
|
||||||
<i>rule</i> as one text line to an in-memory file:
|
parameter value, ignores whitespace after '{' and before '}', and
|
||||||
|
writes each <i>rule</i> as one text line to an in-memory file:
|
||||||
|
|
||||||
in-memory file:
|
in-memory file:
|
||||||
rule-1
|
rule-1
|
||||||
@ -191,12 +192,29 @@ PCRE_TABLE(5) PCRE_TABLE(5)
|
|||||||
|
|
||||||
Postfix parses the result as if it is a file in /etc/postfix.
|
Postfix parses the result as if it is a file in /etc/postfix.
|
||||||
|
|
||||||
Note: if an inlined rule contains <b>$</b>, specify <b>$$</b> to keep Postfix from
|
<b><a name="inline_specification_caveats">INLINE SPECIFICATION CAVEATS</a></b>
|
||||||
trying to do <i>$name</i> expansion as it evaluates a parameter value.
|
<b>o</b> When using <i>$parametername</i> inside an inlined pattern, use
|
||||||
|
\Q<i>$parametername</i>\E to disable metacharacters such as '.' in the
|
||||||
|
<i>$parametername</i> expansion. Otherwise, the pattern may have unex-
|
||||||
|
pected matches.
|
||||||
|
|
||||||
Note: when using <i>$name</i> inside an inlined pattern, use \Q<i>$name</i>\E to dis-
|
<b>o</b> When an inlined rule must contain <b>$</b>, specify <b>$$</b> to keep Postfix
|
||||||
able metacharacters such as '.' in the <i>$name</i> expansion. Otherwise, the
|
from trying to do <i>$name</i> expansion as it evaluates a parameter
|
||||||
pattern may have unexpected matches.
|
value. To check an inline configuration, use the "<b>postconf -x</b>"
|
||||||
|
option as shown below:
|
||||||
|
|
||||||
|
<b>o</b> When a <a href="postconf.5.html">main.cf</a> "<i>parametername = value</i>" setting contains
|
||||||
|
an inline <a href="pcre_table.5.html">pcre</a>: table, use the command "<b>postconf -x</b>
|
||||||
|
<i>parametername</i>". Verify that there are no "undefined
|
||||||
|
parameter" warnings, and that the output has the syntax
|
||||||
|
that one would use in a non-inlined Postfix <a href="pcre_table.5.html">pcre</a>: file.
|
||||||
|
|
||||||
|
<b>o</b> When a <a href="master.5.html">master.cf</a> "<b>-o {</b> <i>parametername = value</i> <b>}</b>" override
|
||||||
|
contains an inline <a href="pcre_table.5.html">pcre</a>: table, use the command "<b>postconf</b>
|
||||||
|
<b>-Px '*/*/</b><i>parametername</i><b>'</b> ". Verify that there are no
|
||||||
|
"undefined parameter" warnings, and that the output has
|
||||||
|
the syntax that one would use in a non-inlined Postfix
|
||||||
|
<a href="pcre_table.5.html">pcre</a>: file.
|
||||||
|
|
||||||
<b><a name="example_smtpd_access_map">EXAMPLE SMTPD ACCESS MAP</a></b>
|
<b><a name="example_smtpd_access_map">EXAMPLE SMTPD ACCESS MAP</a></b>
|
||||||
# Protect your outgoing majordomo exploders
|
# Protect your outgoing majordomo exploders
|
||||||
|
@ -48,7 +48,7 @@ PGSQL_TABLE(5) PGSQL_TABLE(5)
|
|||||||
<b>inet:</b><i>host:port</i> for TCP connections, where the <b>unix:</b> and <b>inet:</b>
|
<b>inet:</b><i>host:port</i> for TCP connections, where the <b>unix:</b> and <b>inet:</b>
|
||||||
prefixes are accepted and ignored for backwards compatibility.
|
prefixes are accepted and ignored for backwards compatibility.
|
||||||
Examples:
|
Examples:
|
||||||
hosts = postgresql://username@example.com/tablename?sslmode=require
|
hosts = postgresql://username@example.com/<i>databasename</i>?sslmode=require
|
||||||
hosts = inet:host1.some.domain inet:host2.some.domain:port
|
hosts = inet:host1.some.domain inet:host2.some.domain:port
|
||||||
hosts = host1.some.domain host2.some.domain:port
|
hosts = host1.some.domain host2.some.domain:port
|
||||||
hosts = unix:/file/name
|
hosts = unix:/file/name
|
||||||
@ -71,21 +71,25 @@ PGSQL_TABLE(5) PGSQL_TABLE(5)
|
|||||||
user = someone
|
user = someone
|
||||||
password = some_password
|
password = some_password
|
||||||
|
|
||||||
<b>dbname</b> The database name on the servers. Example:
|
<b>dbname</b> (required)
|
||||||
|
The database name on the servers. Example:
|
||||||
dbname = customer_database
|
dbname = customer_database
|
||||||
|
|
||||||
|
This setting is required, but ignored when a postgresql:// URI
|
||||||
|
specifies a database name.
|
||||||
|
|
||||||
<b>encoding</b>
|
<b>encoding</b>
|
||||||
The encoding used by the database client. The default setting
|
The encoding used by the database client. The default setting
|
||||||
is:
|
is:
|
||||||
encoding = UTF8
|
encoding = UTF8
|
||||||
|
|
||||||
Historically, the database client was hard coded to use LATIN1
|
Historically, the database client was hard coded to use LATIN1
|
||||||
in an attempt to disable multibyte character support.
|
in an attempt to disable multibyte character support.
|
||||||
|
|
||||||
This feature is available in Postfix 3.8 and later.
|
This feature is available in Postfix 3.8 and later.
|
||||||
|
|
||||||
<b>idle_interval (default: 60)</b>
|
<b>idle_interval (default: 60)</b>
|
||||||
The number of seconds after which an idle database connection
|
The number of seconds after which an idle database connection
|
||||||
will be closed.
|
will be closed.
|
||||||
|
|
||||||
This feature is available in Postfix 3.9 and later.
|
This feature is available in Postfix 3.9 and later.
|
||||||
@ -96,8 +100,8 @@ PGSQL_TABLE(5) PGSQL_TABLE(5)
|
|||||||
|
|
||||||
This feature is available in Postfix 3.9 and later.
|
This feature is available in Postfix 3.9 and later.
|
||||||
|
|
||||||
<b>query</b> The SQL query template used to search the database, where <b>%s</b> is
|
<b>query</b> The SQL query template used to search the database, where <b>%s</b> is
|
||||||
a substitute for the address Postfix is trying to resolve, e.g.
|
a substitute for the address Postfix is trying to resolve, e.g.
|
||||||
query = SELECT replacement FROM aliases WHERE mailbox = '%s'
|
query = SELECT replacement FROM aliases WHERE mailbox = '%s'
|
||||||
|
|
||||||
This parameter supports the following '%' expansions:
|
This parameter supports the following '%' expansions:
|
||||||
@ -105,48 +109,48 @@ PGSQL_TABLE(5) PGSQL_TABLE(5)
|
|||||||
<b>%%</b> This is replaced by a literal '%' character. (Postfix 2.2
|
<b>%%</b> This is replaced by a literal '%' character. (Postfix 2.2
|
||||||
and later)
|
and later)
|
||||||
|
|
||||||
<b>%s</b> This is replaced by the input key. SQL quoting is used
|
<b>%s</b> This is replaced by the input key. SQL quoting is used
|
||||||
to make sure that the input key does not add unexpected
|
to make sure that the input key does not add unexpected
|
||||||
metacharacters.
|
metacharacters.
|
||||||
|
|
||||||
<b>%u</b> When the input key is an address of the form user@domain,
|
<b>%u</b> When the input key is an address of the form user@domain,
|
||||||
<b>%u</b> is replaced by the SQL quoted local part of the
|
<b>%u</b> is replaced by the SQL quoted local part of the
|
||||||
address. Otherwise, <b>%u</b> is replaced by the entire search
|
address. Otherwise, <b>%u</b> is replaced by the entire search
|
||||||
string. If the localpart is empty, the query is sup-
|
string. If the localpart is empty, the query is sup-
|
||||||
pressed and returns no results.
|
pressed and returns no results.
|
||||||
|
|
||||||
<b>%d</b> When the input key is an address of the form user@domain,
|
<b>%d</b> When the input key is an address of the form user@domain,
|
||||||
<b>%d</b> is replaced by the SQL quoted domain part of the
|
<b>%d</b> is replaced by the SQL quoted domain part of the
|
||||||
address. Otherwise, the query is suppressed and returns
|
address. Otherwise, the query is suppressed and returns
|
||||||
no results.
|
no results.
|
||||||
|
|
||||||
<b>%[SUD]</b> The upper-case equivalents of the above expansions behave
|
<b>%[SUD]</b> The upper-case equivalents of the above expansions behave
|
||||||
in the <b>query</b> parameter identically to their lower-case
|
in the <b>query</b> parameter identically to their lower-case
|
||||||
counter-parts. With the <b>result_format</b> parameter (see
|
counter-parts. With the <b>result_format</b> parameter (see
|
||||||
below), they expand the input key rather than the result
|
below), they expand the input key rather than the result
|
||||||
value.
|
value.
|
||||||
|
|
||||||
The above %S, %U and %D expansions are available with
|
The above %S, %U and %D expansions are available with
|
||||||
Postfix 2.2 and later
|
Postfix 2.2 and later
|
||||||
|
|
||||||
<b>%[1-9]</b> The patterns %1, %2, ... %9 are replaced by the corre-
|
<b>%[1-9]</b> The patterns %1, %2, ... %9 are replaced by the corre-
|
||||||
sponding most significant component of the input key's
|
sponding most significant component of the input key's
|
||||||
domain. If the input key is <i>user@mail.example.com</i>, then
|
domain. If the input key is <i>user@mail.example.com</i>, then
|
||||||
%1 is <b>com</b>, %2 is <b>example</b> and %3 is <b>mail</b>. If the input key
|
%1 is <b>com</b>, %2 is <b>example</b> and %3 is <b>mail</b>. If the input key
|
||||||
is unqualified or does not have enough domain components
|
is unqualified or does not have enough domain components
|
||||||
to satisfy all the specified patterns, the query is sup-
|
to satisfy all the specified patterns, the query is sup-
|
||||||
pressed and returns no results.
|
pressed and returns no results.
|
||||||
|
|
||||||
The above %1, ... %9 expansions are available with Post-
|
The above %1, ... %9 expansions are available with Post-
|
||||||
fix 2.2 and later
|
fix 2.2 and later
|
||||||
|
|
||||||
The <b>domain</b> parameter described below limits the input keys to
|
The <b>domain</b> parameter described below limits the input keys to
|
||||||
addresses in matching domains. When the <b>domain</b> parameter is
|
addresses in matching domains. When the <b>domain</b> parameter is
|
||||||
non-empty, SQL queries for unqualified addresses or addresses in
|
non-empty, SQL queries for unqualified addresses or addresses in
|
||||||
non-matching domains are suppressed and return no results.
|
non-matching domains are suppressed and return no results.
|
||||||
|
|
||||||
The precedence of this parameter has changed with Postfix 2.2,
|
The precedence of this parameter has changed with Postfix 2.2,
|
||||||
in prior releases the precedence was, from highest to lowest,
|
in prior releases the precedence was, from highest to lowest,
|
||||||
<b>select_function</b>, <b>query</b>, <b>select_field</b>, ...
|
<b>select_function</b>, <b>query</b>, <b>select_field</b>, ...
|
||||||
|
|
||||||
With Postfix 2.2 the <b>query</b> parameter has highest precedence, see
|
With Postfix 2.2 the <b>query</b> parameter has highest precedence, see
|
||||||
@ -156,42 +160,42 @@ PGSQL_TABLE(5) PGSQL_TABLE(5)
|
|||||||
|
|
||||||
<b>result_format (default: %s</b>)
|
<b>result_format (default: %s</b>)
|
||||||
Format template applied to result attributes. Most commonly used
|
Format template applied to result attributes. Most commonly used
|
||||||
to append (or prepend) text to the result. This parameter sup-
|
to append (or prepend) text to the result. This parameter sup-
|
||||||
ports the following '%' expansions:
|
ports the following '%' expansions:
|
||||||
|
|
||||||
<b>%%</b> This is replaced by a literal '%' character.
|
<b>%%</b> This is replaced by a literal '%' character.
|
||||||
|
|
||||||
<b>%s</b> This is replaced by the value of the result attribute.
|
<b>%s</b> This is replaced by the value of the result attribute.
|
||||||
When result is empty it is skipped.
|
When result is empty it is skipped.
|
||||||
|
|
||||||
<b>%u</b> When the result attribute value is an address of the form
|
<b>%u</b> When the result attribute value is an address of the form
|
||||||
user@domain, <b>%u</b> is replaced by the local part of the
|
user@domain, <b>%u</b> is replaced by the local part of the
|
||||||
address. When the result has an empty localpart it is
|
address. When the result has an empty localpart it is
|
||||||
skipped.
|
skipped.
|
||||||
|
|
||||||
<b>%d</b> When a result attribute value is an address of the form
|
<b>%d</b> When a result attribute value is an address of the form
|
||||||
user@domain, <b>%d</b> is replaced by the domain part of the
|
user@domain, <b>%d</b> is replaced by the domain part of the
|
||||||
attribute value. When the result is unqualified it is
|
attribute value. When the result is unqualified it is
|
||||||
skipped.
|
skipped.
|
||||||
|
|
||||||
<b>%[SUD1-9]</b>
|
<b>%[SUD1-9]</b>
|
||||||
The upper-case and decimal digit expansions interpolate
|
The upper-case and decimal digit expansions interpolate
|
||||||
the parts of the input key rather than the result. Their
|
the parts of the input key rather than the result. Their
|
||||||
behavior is identical to that described with <b>query</b>, and
|
behavior is identical to that described with <b>query</b>, and
|
||||||
in fact because the input key is known in advance,
|
in fact because the input key is known in advance,
|
||||||
queries whose key does not contain all the information
|
queries whose key does not contain all the information
|
||||||
specified in the result template are suppressed and
|
specified in the result template are suppressed and
|
||||||
return no results.
|
return no results.
|
||||||
|
|
||||||
For example, using "result_format = <a href="smtp.8.html">smtp</a>:[%s]" allows one to use
|
For example, using "result_format = <a href="smtp.8.html">smtp</a>:[%s]" allows one to use
|
||||||
a mailHost attribute as the basis of a <a href="transport.5.html">transport(5)</a> table. After
|
a mailHost attribute as the basis of a <a href="transport.5.html">transport(5)</a> table. After
|
||||||
applying the result format, multiple values are concatenated as
|
applying the result format, multiple values are concatenated as
|
||||||
comma separated strings. The expansion_limit and parameter
|
comma separated strings. The expansion_limit and parameter
|
||||||
explained below allows one to restrict the number of values in
|
explained below allows one to restrict the number of values in
|
||||||
the result, which is especially useful for maps that must return
|
the result, which is especially useful for maps that must return
|
||||||
at most one value.
|
at most one value.
|
||||||
|
|
||||||
The default value <b>%s</b> specifies that each result value should be
|
The default value <b>%s</b> specifies that each result value should be
|
||||||
used as is.
|
used as is.
|
||||||
|
|
||||||
This parameter is available with Postfix 2.2 and later.
|
This parameter is available with Postfix 2.2 and later.
|
||||||
@ -199,15 +203,15 @@ PGSQL_TABLE(5) PGSQL_TABLE(5)
|
|||||||
NOTE: DO NOT put quotes around the result format!
|
NOTE: DO NOT put quotes around the result format!
|
||||||
|
|
||||||
<b>domain (default: no domain list)</b>
|
<b>domain (default: no domain list)</b>
|
||||||
This is a list of domain names, paths to files, or "<a href="DATABASE_README.html">type:table</a>"
|
This is a list of domain names, paths to files, or "<a href="DATABASE_README.html">type:table</a>"
|
||||||
databases. When specified, only fully qualified search keys with
|
databases. When specified, only fully qualified search keys with
|
||||||
a *non-empty* localpart and a matching domain are eligible for
|
a *non-empty* localpart and a matching domain are eligible for
|
||||||
lookup: 'user' lookups, bare domain lookups and "@domain"
|
lookup: 'user' lookups, bare domain lookups and "@domain"
|
||||||
lookups are not performed. This can significantly reduce the
|
lookups are not performed. This can significantly reduce the
|
||||||
query load on the PostgreSQL server.
|
query load on the PostgreSQL server.
|
||||||
domain = postfix.org, <a href="DATABASE_README.html#types">hash</a>:/etc/postfix/searchdomains
|
domain = postfix.org, <a href="DATABASE_README.html#types">hash</a>:/etc/postfix/searchdomains
|
||||||
|
|
||||||
It is best not to use SQL to store the domains eligible for SQL
|
It is best not to use SQL to store the domains eligible for SQL
|
||||||
lookups.
|
lookups.
|
||||||
|
|
||||||
This parameter is available with Postfix 2.2 and later.
|
This parameter is available with Postfix 2.2 and later.
|
||||||
@ -216,28 +220,28 @@ PGSQL_TABLE(5) PGSQL_TABLE(5)
|
|||||||
the input keys are always unqualified.
|
the input keys are always unqualified.
|
||||||
|
|
||||||
<b>expansion_limit (default: 0)</b>
|
<b>expansion_limit (default: 0)</b>
|
||||||
A limit on the total number of result elements returned (as a
|
A limit on the total number of result elements returned (as a
|
||||||
comma separated list) by a lookup against the map. A setting of
|
comma separated list) by a lookup against the map. A setting of
|
||||||
zero disables the limit. Lookups fail with a temporary error if
|
zero disables the limit. Lookups fail with a temporary error if
|
||||||
the limit is exceeded. Setting the limit to 1 ensures that
|
the limit is exceeded. Setting the limit to 1 ensures that
|
||||||
lookups do not return multiple values.
|
lookups do not return multiple values.
|
||||||
|
|
||||||
<b>OBSOLETE MAIN.CF PARAMETERS</b>
|
<b>OBSOLETE MAIN.CF PARAMETERS</b>
|
||||||
For compatibility with other Postfix lookup tables, PostgreSQL parame-
|
For compatibility with other Postfix lookup tables, PostgreSQL parame-
|
||||||
ters can also be defined in <a href="postconf.5.html">main.cf</a>. In order to do that, specify as
|
ters can also be defined in <a href="postconf.5.html">main.cf</a>. In order to do that, specify as
|
||||||
PostgreSQL source a name that doesn't begin with a slash or a dot. The
|
PostgreSQL source a name that doesn't begin with a slash or a dot. The
|
||||||
PostgreSQL parameters will then be accessible as the name you've given
|
PostgreSQL parameters will then be accessible as the name you've given
|
||||||
the source in its definition, an underscore, and the name of the param-
|
the source in its definition, an underscore, and the name of the param-
|
||||||
eter. For example, if the map is specified as "<a href="pgsql_table.5.html">pgsql</a>:<i>pgsqlname</i>", the
|
eter. For example, if the map is specified as "<a href="pgsql_table.5.html">pgsql</a>:<i>pgsqlname</i>", the
|
||||||
parameter "hosts" would be defined in <a href="postconf.5.html">main.cf</a> as "<i>pgsqlname</i>_hosts".
|
parameter "hosts" would be defined in <a href="postconf.5.html">main.cf</a> as "<i>pgsqlname</i>_hosts".
|
||||||
|
|
||||||
Note: with this form, the passwords for the PostgreSQL sources are
|
Note: with this form, the passwords for the PostgreSQL sources are
|
||||||
written in <a href="postconf.5.html">main.cf</a>, which is normally world-readable. Support for this
|
written in <a href="postconf.5.html">main.cf</a>, which is normally world-readable. Support for this
|
||||||
form will be removed in a future Postfix version.
|
form will be removed in a future Postfix version.
|
||||||
|
|
||||||
<b><a name="obsolete_query_interfaces">OBSOLETE QUERY INTERFACES</a></b>
|
<b><a name="obsolete_query_interfaces">OBSOLETE QUERY INTERFACES</a></b>
|
||||||
This section describes query interfaces that are deprecated as of Post-
|
This section describes query interfaces that are deprecated as of Post-
|
||||||
fix 2.2. Please migrate to the new <b>query</b> interface as the old inter-
|
fix 2.2. Please migrate to the new <b>query</b> interface as the old inter-
|
||||||
faces are slated to be phased out.
|
faces are slated to be phased out.
|
||||||
|
|
||||||
<b>select_function</b>
|
<b>select_function</b>
|
||||||
@ -247,14 +251,14 @@ PGSQL_TABLE(5) PGSQL_TABLE(5)
|
|||||||
This is equivalent to:
|
This is equivalent to:
|
||||||
query = SELECT my_lookup_user_alias('%s')
|
query = SELECT my_lookup_user_alias('%s')
|
||||||
|
|
||||||
This parameter overrides the legacy table-related fields
|
This parameter overrides the legacy table-related fields
|
||||||
(described below). With Postfix versions prior to 2.2, it also
|
(described below). With Postfix versions prior to 2.2, it also
|
||||||
overrides the <b>query</b> parameter. Starting with Postfix 2.2, the
|
overrides the <b>query</b> parameter. Starting with Postfix 2.2, the
|
||||||
<b>query</b> parameter has highest precedence, and the <b>select_function</b>
|
<b>query</b> parameter has highest precedence, and the <b>select_function</b>
|
||||||
parameter is deprecated.
|
parameter is deprecated.
|
||||||
|
|
||||||
The following parameters (with lower precedence than the <b>select_func-</b>
|
The following parameters (with lower precedence than the <b>select_func-</b>
|
||||||
<b>tion</b> interface described above) can be used to build the SQL select
|
<b>tion</b> interface described above) can be used to build the SQL select
|
||||||
statement as follows:
|
statement as follows:
|
||||||
|
|
||||||
SELECT [<b>select_field</b>]
|
SELECT [<b>select_field</b>]
|
||||||
@ -262,13 +266,13 @@ PGSQL_TABLE(5) PGSQL_TABLE(5)
|
|||||||
WHERE [<b>where_field</b>] = '%s'
|
WHERE [<b>where_field</b>] = '%s'
|
||||||
[<b>additional_conditions</b>]
|
[<b>additional_conditions</b>]
|
||||||
|
|
||||||
The specifier %s is replaced with each lookup by the lookup key and is
|
The specifier %s is replaced with each lookup by the lookup key and is
|
||||||
escaped so if it contains single quotes or other odd characters, it
|
escaped so if it contains single quotes or other odd characters, it
|
||||||
will not cause a parse error, or worse, a security problem.
|
will not cause a parse error, or worse, a security problem.
|
||||||
|
|
||||||
Starting with Postfix 2.2, this interface is obsoleted by the more gen-
|
Starting with Postfix 2.2, this interface is obsoleted by the more gen-
|
||||||
eral <b>query</b> interface described above. If higher precedence the <b>query</b> or
|
eral <b>query</b> interface described above. If higher precedence the <b>query</b> or
|
||||||
<b>select_function</b> parameters described above are defined, the parameters
|
<b>select_function</b> parameters described above are defined, the parameters
|
||||||
described here are ignored.
|
described here are ignored.
|
||||||
|
|
||||||
<b>select_field</b>
|
<b>select_field</b>
|
||||||
|
@ -138,8 +138,9 @@ REGEXP_TABLE(5) REGEXP_TABLE(5)
|
|||||||
<a href="master.5.html">master.cf</a>:
|
<a href="master.5.html">master.cf</a>:
|
||||||
<b>.. -o {</b> <i>parameter</i> <b>= .. <a href="regexp_table.5.html">regexp</a>:{ {</b> <i>rule-1</i> <b>}, {</b> <i>rule-2</i> <b>} .. } .. } ..</b>
|
<b>.. -o {</b> <i>parameter</i> <b>= .. <a href="regexp_table.5.html">regexp</a>:{ {</b> <i>rule-1</i> <b>}, {</b> <i>rule-2</i> <b>} .. } .. } ..</b>
|
||||||
|
|
||||||
Postfix ignores whitespace after '{' and before '}', and writes each
|
Postfix recursively expands any $parametername instances in the above
|
||||||
<i>rule</i> as one text line to an in-memory file:
|
parameter value, ignores whitespace after '{' and before '}', and
|
||||||
|
writes each <i>rule</i> as one text line to an in-memory file:
|
||||||
|
|
||||||
in-memory file:
|
in-memory file:
|
||||||
rule-1
|
rule-1
|
||||||
@ -148,12 +149,30 @@ REGEXP_TABLE(5) REGEXP_TABLE(5)
|
|||||||
|
|
||||||
Postfix parses the result as if it is a file in /etc/postfix.
|
Postfix parses the result as if it is a file in /etc/postfix.
|
||||||
|
|
||||||
Note: if an inlined rule contains <b>$</b>, specify <b>$$</b> to keep Postfix from
|
<b><a name="inline_specification_caveats">INLINE SPECIFICATION CAVEATS</a></b>
|
||||||
trying to do <i>$name</i> expansion as it evaluates a parameter value.
|
<b>o</b> Avoid using <i>$parametername</i> inside an inlined <a href="regexp_table.5.html">regexp</a>: pattern.
|
||||||
|
The pattern would have unexpected matches when there are
|
||||||
|
metacharacters such as '.' in the <i>$parametername</i> expansion. To
|
||||||
|
prevent unexpected matches, use a <a href="pcre_table.5.html">pcre</a>: table, and specify
|
||||||
|
\Q<i>$parametername</i>\E.
|
||||||
|
|
||||||
Note: when using <i>$name</i> inside an inlined pattern, this will not disable
|
<b>o</b> When an inlined rule must contain <b>$</b>, specify <b>$$</b> to keep Postfix
|
||||||
metacharacters such as '.' in the <i>$name</i> expansion. To prevent unex-
|
from trying to do <i>$name</i> expansion as it evaluates a parameter
|
||||||
pected matches, use a <a href="pcre_table.5.html">pcre</a>: table, and specify \Q<i>$name</i>\E.
|
value. To check an inline configuration, use the "<b>postconf -x</b>"
|
||||||
|
option as shown below:
|
||||||
|
|
||||||
|
<b>o</b> When a <a href="postconf.5.html">main.cf</a> "<i>parametername = value</i>" setting contains
|
||||||
|
an inline <a href="regexp_table.5.html">regexp</a>: table, use the command "<b>postconf -x</b>
|
||||||
|
<i>parametername</i>". Verify that there are no "undefined
|
||||||
|
parameter" warnings, and that the output has the syntax
|
||||||
|
that one would use in a non-inlined Postfix <a href="regexp_table.5.html">regexp</a>: file.
|
||||||
|
|
||||||
|
<b>o</b> When a <a href="master.5.html">master.cf</a> "<b>-o {</b> <i>parametername = value</i> <b>}</b>" override
|
||||||
|
contains an inline <a href="regexp_table.5.html">regexp</a>: table, use the command "<b>post-</b>
|
||||||
|
<b>conf -Px '*/*/</b><i>parametername</i><b>'</b> ". Verify that there are no
|
||||||
|
"undefined parameter" warnings, and that the output has
|
||||||
|
the syntax that one would use in a non-inlined Postfix
|
||||||
|
<a href="regexp_table.5.html">regexp</a>: file.
|
||||||
|
|
||||||
<b><a name="example_smtpd_access_map">EXAMPLE SMTPD ACCESS MAP</a></b>
|
<b><a name="example_smtpd_access_map">EXAMPLE SMTPD ACCESS MAP</a></b>
|
||||||
# Disallow sender-specified routing. This is a must if you relay mail
|
# Disallow sender-specified routing. This is a must if you relay mail
|
||||||
|
@ -127,9 +127,10 @@ master.cf:
|
|||||||
\fB.. \-o { \fIparameter\fR \fB= .. cidr:{ { \fIrule\-1\fB }, { \fIrule\-2\fB } .. } .. } ..\fR
|
\fB.. \-o { \fIparameter\fR \fB= .. cidr:{ { \fIrule\-1\fB }, { \fIrule\-2\fB } .. } .. } ..\fR
|
||||||
.fi
|
.fi
|
||||||
|
|
||||||
Postfix ignores whitespace after '{' and before '}', and
|
Postfix recursively expands any \fI$parametername\fR instances
|
||||||
writes each \fIrule\fR as one text line to an in\-memory
|
in the above parameter value, ignores whitespace after '{'
|
||||||
file:
|
and before '}', and writes each \fIrule\fR as one text line to
|
||||||
|
an in\-memory file:
|
||||||
|
|
||||||
.nf
|
.nf
|
||||||
in\-memory file:
|
in\-memory file:
|
||||||
|
@ -193,9 +193,10 @@ master.cf:
|
|||||||
\fB.. \-o { \fIparameter\fR \fB= .. pcre:{ { \fIrule\-1\fB }, { \fIrule\-2\fB } .. } .. } ..\fR
|
\fB.. \-o { \fIparameter\fR \fB= .. pcre:{ { \fIrule\-1\fB }, { \fIrule\-2\fB } .. } .. } ..\fR
|
||||||
.fi
|
.fi
|
||||||
|
|
||||||
Postfix ignores whitespace after '{' and before '}', and
|
Postfix recursively expands any \fI$parametername\fR instances
|
||||||
writes each \fIrule\fR as one text line to an in\-memory
|
in the above parameter value, ignores whitespace after '{'
|
||||||
file:
|
and before '}', and writes each \fIrule\fR as one text line to
|
||||||
|
an in\-memory file:
|
||||||
|
|
||||||
.nf
|
.nf
|
||||||
in\-memory file:
|
in\-memory file:
|
||||||
@ -205,15 +206,35 @@ in\-memory file:
|
|||||||
.fi
|
.fi
|
||||||
|
|
||||||
Postfix parses the result as if it is a file in /etc/postfix.
|
Postfix parses the result as if it is a file in /etc/postfix.
|
||||||
|
.SH "INLINE SPECIFICATION CAVEATS"
|
||||||
Note: if an inlined rule contains \fB$\fR, specify \fB$$\fR
|
.na
|
||||||
|
.nf
|
||||||
|
.ad
|
||||||
|
.fi
|
||||||
|
.IP \(bu
|
||||||
|
When using \fI$parametername\fR inside an inlined pattern,
|
||||||
|
use \eQ\fI$parametername\fR\eE to disable metacharacters such as
|
||||||
|
\&'.' in the \fI$parametername\fR expansion. Otherwise, the pattern
|
||||||
|
may have unexpected matches.
|
||||||
|
.IP \(bu
|
||||||
|
When an inlined rule must contain \fB$\fR, specify \fB$$\fR
|
||||||
to keep Postfix from trying to do \fI$name\fR expansion as
|
to keep Postfix from trying to do \fI$name\fR expansion as
|
||||||
it evaluates a parameter value.
|
it evaluates a parameter value. To check an inline configuration,
|
||||||
|
use the "\fBpostconf \-x\fR" option as shown below:
|
||||||
Note: when using \fI$name\fR inside an inlined pattern, use
|
.RS
|
||||||
\eQ\fI$name\fR\eE to disable metacharacters such as '.' in
|
.IP \(bu
|
||||||
the \fI$name\fR expansion. Otherwise, the pattern may have
|
When a main.cf "\fIparametername = \fI value\fR" setting contains
|
||||||
unexpected matches.
|
an inline pcre: table, use the command "\fBpostconf \-x
|
||||||
|
\fIparametername\fR". Verify that there are no "undefined
|
||||||
|
parameter" warnings, and that the output has the syntax that
|
||||||
|
one would use in a non\-inlined Postfix pcre: file.
|
||||||
|
.IP \(bu
|
||||||
|
When a master.cf "\fB\-o { \fIparametername = value\fB }\fR"
|
||||||
|
override contains an inline pcre: table, use the command
|
||||||
|
"\fBpostconf \-Px '*/*/\fIparametername\fB' \fR". Verify that there
|
||||||
|
are no "undefined parameter" warnings, and that the output has
|
||||||
|
the syntax that one would use in a non\-inlined Postfix pcre: file.
|
||||||
|
.RE
|
||||||
.SH "EXAMPLE SMTPD ACCESS MAP"
|
.SH "EXAMPLE SMTPD ACCESS MAP"
|
||||||
.na
|
.na
|
||||||
.nf
|
.nf
|
||||||
|
@ -62,7 +62,7 @@ connections, where the \fBunix:\fR and \fBinet:\fR prefixes
|
|||||||
are accepted and ignored for backwards compatibility.
|
are accepted and ignored for backwards compatibility.
|
||||||
Examples:
|
Examples:
|
||||||
.nf
|
.nf
|
||||||
hosts = postgresql://username@example.com/tablename?sslmode=require
|
hosts = postgresql://username@example.com/\fIdatabasename\fR?sslmode=require
|
||||||
hosts = inet:host1.some.domain inet:host2.some.domain:port
|
hosts = inet:host1.some.domain inet:host2.some.domain:port
|
||||||
hosts = host1.some.domain host2.some.domain:port
|
hosts = host1.some.domain host2.some.domain:port
|
||||||
hosts = unix:/file/name
|
hosts = unix:/file/name
|
||||||
@ -85,11 +85,14 @@ Example:
|
|||||||
user = someone
|
user = someone
|
||||||
password = some_password
|
password = some_password
|
||||||
.fi
|
.fi
|
||||||
.IP "\fBdbname\fR"
|
.IP "\fBdbname\fR (required)"
|
||||||
The database name on the servers. Example:
|
The database name on the servers. Example:
|
||||||
.nf
|
.nf
|
||||||
dbname = customer_database
|
dbname = customer_database
|
||||||
.fi
|
.fi
|
||||||
|
.sp
|
||||||
|
This setting is required, but ignored when a postgresql://
|
||||||
|
URI specifies a database name.
|
||||||
.IP "\fBencoding\fR"
|
.IP "\fBencoding\fR"
|
||||||
The encoding used by the database client. The default setting
|
The encoding used by the database client. The default setting
|
||||||
is:
|
is:
|
||||||
|
@ -150,9 +150,10 @@ master.cf:
|
|||||||
\fB.. \-o { \fIparameter\fR \fB= .. regexp:{ { \fIrule\-1\fB }, { \fIrule\-2\fB } .. } .. } ..\fR
|
\fB.. \-o { \fIparameter\fR \fB= .. regexp:{ { \fIrule\-1\fB }, { \fIrule\-2\fB } .. } .. } ..\fR
|
||||||
.fi
|
.fi
|
||||||
|
|
||||||
Postfix ignores whitespace after '{' and before '}', and
|
Postfix recursively expands any \fi$parametername\fR instances
|
||||||
writes each \fIrule\fR as one text line to an in\-memory
|
in the above parameter value, ignores whitespace after '{'
|
||||||
file:
|
and before '}', and writes each \fIrule\fR as one text line to
|
||||||
|
an in\-memory file:
|
||||||
|
|
||||||
.nf
|
.nf
|
||||||
in\-memory file:
|
in\-memory file:
|
||||||
@ -162,15 +163,37 @@ in\-memory file:
|
|||||||
.fi
|
.fi
|
||||||
|
|
||||||
Postfix parses the result as if it is a file in /etc/postfix.
|
Postfix parses the result as if it is a file in /etc/postfix.
|
||||||
|
.SH "INLINE SPECIFICATION CAVEATS"
|
||||||
Note: if an inlined rule contains \fB$\fR, specify \fB$$\fR
|
.na
|
||||||
|
.nf
|
||||||
|
.ad
|
||||||
|
.fi
|
||||||
|
.IP \(bu
|
||||||
|
Avoid using \fI$parametername\fR inside an inlined regexp:
|
||||||
|
pattern. The pattern would have unexpected matches when there
|
||||||
|
are metacharacters such as '.' in the \fI$parametername\fR
|
||||||
|
expansion. To prevent unexpected matches, use a pcre: table,
|
||||||
|
and specify \eQ\fI$parametername\fR\eE.
|
||||||
|
.IP \(bu
|
||||||
|
When an inlined rule must contain \fB$\fR, specify \fB$$\fR
|
||||||
to keep Postfix from trying to do \fI$name\fR expansion as
|
to keep Postfix from trying to do \fI$name\fR expansion as
|
||||||
it evaluates a parameter value.
|
it evaluates a parameter value. To check an inline configuration,
|
||||||
|
use the "\fBpostconf \-x\fR" option as shown below:
|
||||||
Note: when using \fI$name\fR inside an inlined pattern,
|
.RS
|
||||||
this will not disable metacharacters such as '.' in the
|
.IP \(bu
|
||||||
\fI$name\fR expansion. To prevent unexpected matches, use
|
When a main.cf "\fIparametername = \fI value\fR" setting
|
||||||
a pcre: table, and specify \eQ\fI$name\fR\eE.
|
contains an inline regexp: table, use the command "\fBpostconf
|
||||||
|
\-x \fIparametername\fR". Verify that there are no "undefined
|
||||||
|
parameter" warnings, and that the output has the syntax that
|
||||||
|
one would use in a non\-inlined Postfix regexp: file.
|
||||||
|
.IP \(bu
|
||||||
|
When a master.cf "\fB\-o { \fIparametername = value\fB }\fR"
|
||||||
|
override contains an inline regexp: table, use the command
|
||||||
|
"\fBpostconf \-Px '*/*/\fIparametername\fB' \fR". Verify that there
|
||||||
|
are no "undefined parameter" warnings, and that the output has
|
||||||
|
the syntax that one would use in a non\-inlined Postfix regexp:
|
||||||
|
file.
|
||||||
|
.RE
|
||||||
.SH "EXAMPLE SMTPD ACCESS MAP"
|
.SH "EXAMPLE SMTPD ACCESS MAP"
|
||||||
.na
|
.na
|
||||||
.nf
|
.nf
|
||||||
|
@ -1267,7 +1267,7 @@ while (<>) {
|
|||||||
s;\b(pipe[-</bB>]*\n*[ <bB>]*map):;<a href="DATABASE_README.html#types">$1<\/a>:;g;
|
s;\b(pipe[-</bB>]*\n*[ <bB>]*map):;<a href="DATABASE_README.html#types">$1<\/a>:;g;
|
||||||
s/\b(proxy):/<a href="proxymap.8.html">$1<\/a>:/g;
|
s/\b(proxy):/<a href="proxymap.8.html">$1<\/a>:/g;
|
||||||
s/\b(randmap):/<a href="DATABASE_README.html#types">$1<\/a>:/g;
|
s/\b(randmap):/<a href="DATABASE_README.html#types">$1<\/a>:/g;
|
||||||
s/\b(regexp):/<a href="regexp_table.5.html">$1<\/a>:/g;
|
s;\b(reg[-</bB>]*\n*[ <bB>]*exp):;<a href="regexp_table.5.html">$1<\/a>:;g;
|
||||||
s/\b(sdbm):/<a href="DATABASE_README.html#types">$1<\/a>:/g;
|
s/\b(sdbm):/<a href="DATABASE_README.html#types">$1<\/a>:/g;
|
||||||
s/\b(socketmap):/<a href="socketmap_table.html">$1<\/a>:/g;
|
s/\b(socketmap):/<a href="socketmap_table.html">$1<\/a>:/g;
|
||||||
s/\b(sqlite):/<a href="sqlite_table.5.html">$1<\/a>:/g;
|
s/\b(sqlite):/<a href="sqlite_table.5.html">$1<\/a>:/g;
|
||||||
|
@ -266,44 +266,51 @@ have the details for why TLS authentication failed. </p>
|
|||||||
|
|
||||||
<h2> <a name="delivering"> Delivering TLSRPT summaries via email</a> </h2>
|
<h2> <a name="delivering"> Delivering TLSRPT summaries via email</a> </h2>
|
||||||
|
|
||||||
<p> RFC 8460 suggests not to enforce strict TLS security when sending
|
<p> <a href="https://datatracker.ietf.org/doc/html/rfc8460#section-3">RFC
|
||||||
daily success/failure summaries via email, to avoid delivery delays
|
8460 Section 3</a> specifies that an MTA must not enforce TLS
|
||||||
caused by a failure to enforce TLS security. Postfix currently does
|
security when sending failure reports via email. However, Postfix
|
||||||
not have a mechanism to disable TLS security enforcement when
|
currently has no way to request that TLS enforcement will be disabled
|
||||||
submitting an email message; this section provides a workaround. </p>
|
when submitting an email message. </p>
|
||||||
|
|
||||||
<p> By design, TLSRPT is not a real-time notification system; it
|
<p> Options:
|
||||||
takes on average 12 hours before a failure is reported in a daily
|
|
||||||
success/failure summary. If a TLS-related delay of a day or more
|
<ul>
|
||||||
is undesirable, one could set up a transport map to make TLS security
|
|
||||||
optional for specific TLSRPT email notification email addresses.
|
<li> <p> Do nothing. When TLS security enforcement is required, a
|
||||||
</p>
|
persistent enforcement failure will delay the delivery of a TLSRPT
|
||||||
|
summary until the problem is addressed, or until the message expires
|
||||||
|
in the mail queue. Keep in mind that TLSRPT is not a real-time
|
||||||
|
monitoring service; it takes on average 12 hours before a failure
|
||||||
|
is reported through TLSRPT. </p>
|
||||||
|
|
||||||
|
<li> <p> Exclude the sender of TLSRPT summaries from TLS enforcement.
|
||||||
|
Implement the configuration below on outbound MTA instances (replace
|
||||||
|
noreply-smtp-tls-reporting@example.com with your actual report
|
||||||
|
generator's sender address): </p>
|
||||||
|
|
||||||
<blockquote>
|
|
||||||
<pre>
|
<pre>
|
||||||
/etc/postfix/main.cf:
|
/etc/postfix/main.cf:
|
||||||
transport_maps = hash:/etc/postfix/transport
|
# Limitation: this setting is overruled with transport_maps.
|
||||||
 
|
sender_dependent_default_transport_maps = inline:{
|
||||||
/etc/postfix/transport:
|
{ noreply-smtp-tls-reporting@example.com = allow-plaintext } }
|
||||||
smtp-tls-report@example.com allow-plaintext:
|
|
||||||
...
|
|
||||||
 
|
 
|
||||||
/etc/postfix/master.cf:
|
/etc/postfix/master.cf:
|
||||||
# service name type private unpriv chroot wakeup maxproc command
|
# service name type private unpriv chroot wakeup maxproc command
|
||||||
allow-plaintext unix - - n - - smtp
|
allow-plaintext unix - - n - - smtp
|
||||||
-o smtp_tls_security_level=may
|
-o { smtp_tls_security_level = may }
|
||||||
-o smtp_tls_policy_maps=static:may
|
-o { smtp_tls_policy_maps = static:may }
|
||||||
</pre>
|
</pre>
|
||||||
</blockquote>
|
|
||||||
|
</ul>
|
||||||
|
|
||||||
<h2> <a name="mta-sts"> MTA-STS Support via smtp_tls_policy_maps
|
<h2> <a name="mta-sts"> MTA-STS Support via smtp_tls_policy_maps
|
||||||
</a></h2>
|
</a></h2>
|
||||||
|
|
||||||
<p> Postfix supports MTA-STS though an smtp_tls_policy_maps
|
<p> Postfix supports MTA-STS though an smtp_tls_policy_maps policy
|
||||||
policy plugin. Postfix 3.10 and later expect a policy response with
|
plugin, which replies with a TLS security level and optional matching
|
||||||
the usual security level and matching requirements, plus any
|
requirements. Postfix 3.10 and later optionally also accept the
|
||||||
applicable name=value attributes described below. Specify <tt>{
|
name=value attributes described below. Specify <tt>{ name = value
|
||||||
name = value }</tt> when a value may contain whitespace. </p>
|
}</tt> when a value may contain whitespace. </p>
|
||||||
|
|
||||||
<blockquote>
|
<blockquote>
|
||||||
|
|
||||||
@ -319,8 +326,22 @@ policy. </p>
|
|||||||
</blockquote>
|
</blockquote>
|
||||||
|
|
||||||
<p> The examples in the table apply to the MTA-STS policy example
|
<p> The examples in the table apply to the MTA-STS policy example
|
||||||
given in https://datatracker.ietf.org/doc/html/rfc8460#section-4.5.
|
given in <a
|
||||||
<p>
|
href="https://datatracker.ietf.org/doc/html/rfc8461#section-3.2">
|
||||||
|
RFC 8461 Section 3.2</a>: </p>
|
||||||
|
|
||||||
|
<blockquote>
|
||||||
|
<pre>
|
||||||
|
version: STSv1
|
||||||
|
mode: enforce
|
||||||
|
mx: mail.example.com
|
||||||
|
mx: *.example.net
|
||||||
|
mx: backupmx.example.com
|
||||||
|
max_age: 604800
|
||||||
|
</pre>
|
||||||
|
</blockquote>
|
||||||
|
|
||||||
|
<p> A policy response may contain line breaks. </p>
|
||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
|
|
||||||
@ -347,7 +368,7 @@ in attribute values. </p>
|
|||||||
|
|
||||||
<blockquote>
|
<blockquote>
|
||||||
<pre>
|
<pre>
|
||||||
{ policy_string = version: STSv1 } { policy_string = mode: testing } ...
|
{ policy_string = version: STSv1 } { policy_string = mode: enforce } ...
|
||||||
</pre>
|
</pre>
|
||||||
</blockquote>
|
</blockquote>
|
||||||
|
|
||||||
@ -363,7 +384,7 @@ in the MTA-STS policy. </p>
|
|||||||
|
|
||||||
<blockquote>
|
<blockquote>
|
||||||
<pre>
|
<pre>
|
||||||
mx_host_pattern=mx1.example.com mx_host_pattern=mx2.example.com ...
|
mx_host_pattern=mail.example.com mx_host_pattern=*.example.net ...
|
||||||
</pre>
|
</pre>
|
||||||
</blockquote>
|
</blockquote>
|
||||||
</li>
|
</li>
|
||||||
|
@ -113,9 +113,10 @@
|
|||||||
# \fB.. -o { \fIparameter\fR \fB= .. cidr:{ { \fIrule-1\fB }, { \fIrule-2\fB } .. } .. } ..\fR
|
# \fB.. -o { \fIparameter\fR \fB= .. cidr:{ { \fIrule-1\fB }, { \fIrule-2\fB } .. } .. } ..\fR
|
||||||
# .fi
|
# .fi
|
||||||
#
|
#
|
||||||
# Postfix ignores whitespace after '{' and before '}', and
|
# Postfix recursively expands any \fI$parametername\fR instances
|
||||||
# writes each \fIrule\fR as one text line to an in-memory
|
# in the above parameter value, ignores whitespace after '{'
|
||||||
# file:
|
# and before '}', and writes each \fIrule\fR as one text line to
|
||||||
|
# an in-memory file:
|
||||||
#
|
#
|
||||||
# .nf
|
# .nf
|
||||||
# in-memory file:
|
# in-memory file:
|
||||||
|
@ -177,9 +177,10 @@
|
|||||||
# \fB.. -o { \fIparameter\fR \fB= .. pcre:{ { \fIrule-1\fB }, { \fIrule-2\fB } .. } .. } ..\fR
|
# \fB.. -o { \fIparameter\fR \fB= .. pcre:{ { \fIrule-1\fB }, { \fIrule-2\fB } .. } .. } ..\fR
|
||||||
# .fi
|
# .fi
|
||||||
#
|
#
|
||||||
# Postfix ignores whitespace after '{' and before '}', and
|
# Postfix recursively expands any \fI$parametername\fR instances
|
||||||
# writes each \fIrule\fR as one text line to an in-memory
|
# in the above parameter value, ignores whitespace after '{'
|
||||||
# file:
|
# and before '}', and writes each \fIrule\fR as one text line to
|
||||||
|
# an in-memory file:
|
||||||
#
|
#
|
||||||
# .nf
|
# .nf
|
||||||
# in-memory file:
|
# in-memory file:
|
||||||
@ -189,15 +190,33 @@
|
|||||||
# .fi
|
# .fi
|
||||||
#
|
#
|
||||||
# Postfix parses the result as if it is a file in /etc/postfix.
|
# Postfix parses the result as if it is a file in /etc/postfix.
|
||||||
#
|
# INLINE SPECIFICATION CAVEATS
|
||||||
# Note: if an inlined rule contains \fB$\fR, specify \fB$$\fR
|
# .ad
|
||||||
|
# .fi
|
||||||
|
# .IP \(bu
|
||||||
|
# When using \fI$parametername\fR inside an inlined pattern,
|
||||||
|
# use \eQ\fI$parametername\fR\eE to disable metacharacters such as
|
||||||
|
# '.' in the \fI$parametername\fR expansion. Otherwise, the pattern
|
||||||
|
# may have unexpected matches.
|
||||||
|
# .IP \(bu
|
||||||
|
# When an inlined rule must contain \fB$\fR, specify \fB$$\fR
|
||||||
# to keep Postfix from trying to do \fI$name\fR expansion as
|
# to keep Postfix from trying to do \fI$name\fR expansion as
|
||||||
# it evaluates a parameter value.
|
# it evaluates a parameter value. To check an inline configuration,
|
||||||
#
|
# use the "\fBpostconf -x\fR" option as shown below:
|
||||||
# Note: when using \fI$name\fR inside an inlined pattern, use
|
# .RS
|
||||||
# \eQ\fI$name\fR\eE to disable metacharacters such as '.' in
|
# .IP \(bu
|
||||||
# the \fI$name\fR expansion. Otherwise, the pattern may have
|
# When a main.cf "\fIparametername = \fI value\fR" setting contains
|
||||||
# unexpected matches.
|
# an inline pcre: table, use the command "\fBpostconf -x
|
||||||
|
# \fIparametername\fR". Verify that there are no "undefined
|
||||||
|
# parameter" warnings, and that the output has the syntax that
|
||||||
|
# one would use in a non-inlined Postfix pcre: file.
|
||||||
|
# .IP \(bu
|
||||||
|
# When a master.cf "\fB-o { \fIparametername = value\fB }\fR"
|
||||||
|
# override contains an inline pcre: table, use the command
|
||||||
|
# "\fBpostconf -Px '*/*/\fIparametername\fB' \fR". Verify that there
|
||||||
|
# are no "undefined parameter" warnings, and that the output has
|
||||||
|
# the syntax that one would use in a non-inlined Postfix pcre: file.
|
||||||
|
# .RE
|
||||||
# EXAMPLE SMTPD ACCESS MAP
|
# EXAMPLE SMTPD ACCESS MAP
|
||||||
# # Protect your outgoing majordomo exploders
|
# # Protect your outgoing majordomo exploders
|
||||||
# /^(?!owner-)(.*)-outgoing@(.*)/ 550 Use ${1}@${2} instead
|
# /^(?!owner-)(.*)-outgoing@(.*)/ 550 Use ${1}@${2} instead
|
||||||
|
@ -52,7 +52,7 @@
|
|||||||
# are accepted and ignored for backwards compatibility.
|
# are accepted and ignored for backwards compatibility.
|
||||||
# Examples:
|
# Examples:
|
||||||
# .nf
|
# .nf
|
||||||
# hosts = postgresql://username@example.com/tablename?sslmode=require
|
# hosts = postgresql://username@example.com/\fIdatabasename\fR?sslmode=require
|
||||||
# hosts = inet:host1.some.domain inet:host2.some.domain:port
|
# hosts = inet:host1.some.domain inet:host2.some.domain:port
|
||||||
# hosts = host1.some.domain host2.some.domain:port
|
# hosts = host1.some.domain host2.some.domain:port
|
||||||
# hosts = unix:/file/name
|
# hosts = unix:/file/name
|
||||||
@ -75,11 +75,14 @@
|
|||||||
# user = someone
|
# user = someone
|
||||||
# password = some_password
|
# password = some_password
|
||||||
# .fi
|
# .fi
|
||||||
# .IP "\fBdbname\fR"
|
# .IP "\fBdbname\fR (required)"
|
||||||
# The database name on the servers. Example:
|
# The database name on the servers. Example:
|
||||||
# .nf
|
# .nf
|
||||||
# dbname = customer_database
|
# dbname = customer_database
|
||||||
# .fi
|
# .fi
|
||||||
|
# .sp
|
||||||
|
# This setting is required, but ignored when a postgresql://
|
||||||
|
# URI specifies a database name.
|
||||||
# .IP "\fBencoding\fR"
|
# .IP "\fBencoding\fR"
|
||||||
# The encoding used by the database client. The default setting
|
# The encoding used by the database client. The default setting
|
||||||
# is:
|
# is:
|
||||||
|
@ -134,9 +134,10 @@
|
|||||||
# \fB.. -o { \fIparameter\fR \fB= .. regexp:{ { \fIrule-1\fB }, { \fIrule-2\fB } .. } .. } ..\fR
|
# \fB.. -o { \fIparameter\fR \fB= .. regexp:{ { \fIrule-1\fB }, { \fIrule-2\fB } .. } .. } ..\fR
|
||||||
# .fi
|
# .fi
|
||||||
#
|
#
|
||||||
# Postfix ignores whitespace after '{' and before '}', and
|
# Postfix recursively expands any \fi$parametername\fR instances
|
||||||
# writes each \fIrule\fR as one text line to an in-memory
|
# in the above parameter value, ignores whitespace after '{'
|
||||||
# file:
|
# and before '}', and writes each \fIrule\fR as one text line to
|
||||||
|
# an in-memory file:
|
||||||
#
|
#
|
||||||
# .nf
|
# .nf
|
||||||
# in-memory file:
|
# in-memory file:
|
||||||
@ -146,15 +147,35 @@
|
|||||||
# .fi
|
# .fi
|
||||||
#
|
#
|
||||||
# Postfix parses the result as if it is a file in /etc/postfix.
|
# Postfix parses the result as if it is a file in /etc/postfix.
|
||||||
#
|
# INLINE SPECIFICATION CAVEATS
|
||||||
# Note: if an inlined rule contains \fB$\fR, specify \fB$$\fR
|
# .ad
|
||||||
|
# .fi
|
||||||
|
# .IP \(bu
|
||||||
|
# Avoid using \fI$parametername\fR inside an inlined regexp:
|
||||||
|
# pattern. The pattern would have unexpected matches when there
|
||||||
|
# are metacharacters such as '.' in the \fI$parametername\fR
|
||||||
|
# expansion. To prevent unexpected matches, use a pcre: table,
|
||||||
|
# and specify \eQ\fI$parametername\fR\eE.
|
||||||
|
# .IP \(bu
|
||||||
|
# When an inlined rule must contain \fB$\fR, specify \fB$$\fR
|
||||||
# to keep Postfix from trying to do \fI$name\fR expansion as
|
# to keep Postfix from trying to do \fI$name\fR expansion as
|
||||||
# it evaluates a parameter value.
|
# it evaluates a parameter value. To check an inline configuration,
|
||||||
#
|
# use the "\fBpostconf -x\fR" option as shown below:
|
||||||
# Note: when using \fI$name\fR inside an inlined pattern,
|
# .RS
|
||||||
# this will not disable metacharacters such as '.' in the
|
# .IP \(bu
|
||||||
# \fI$name\fR expansion. To prevent unexpected matches, use
|
# When a main.cf "\fIparametername = \fI value\fR" setting
|
||||||
# a pcre: table, and specify \eQ\fI$name\fR\eE.
|
# contains an inline regexp: table, use the command "\fBpostconf
|
||||||
|
# -x \fIparametername\fR". Verify that there are no "undefined
|
||||||
|
# parameter" warnings, and that the output has the syntax that
|
||||||
|
# one would use in a non-inlined Postfix regexp: file.
|
||||||
|
# .IP \(bu
|
||||||
|
# When a master.cf "\fB-o { \fIparametername = value\fB }\fR"
|
||||||
|
# override contains an inline regexp: table, use the command
|
||||||
|
# "\fBpostconf -Px '*/*/\fIparametername\fB' \fR". Verify that there
|
||||||
|
# are no "undefined parameter" warnings, and that the output has
|
||||||
|
# the syntax that one would use in a non-inlined Postfix regexp:
|
||||||
|
# file.
|
||||||
|
# .RE
|
||||||
# EXAMPLE SMTPD ACCESS MAP
|
# EXAMPLE SMTPD ACCESS MAP
|
||||||
# # Disallow sender-specified routing. This is a must if you relay mail
|
# # Disallow sender-specified routing. This is a must if you relay mail
|
||||||
# # for other domains.
|
# # for other domains.
|
||||||
|
@ -1847,3 +1847,6 @@ sts
|
|||||||
tlsrprt
|
tlsrprt
|
||||||
bdefhnoqv
|
bdefhnoqv
|
||||||
deduplicated
|
deduplicated
|
||||||
|
WS
|
||||||
|
isspace
|
||||||
|
ws
|
||||||
|
@ -85,3 +85,4 @@ pkgconf
|
|||||||
testfiles
|
testfiles
|
||||||
Antonin
|
Antonin
|
||||||
Verrier
|
Verrier
|
||||||
|
unescaped
|
||||||
|
@ -387,3 +387,5 @@ Sys
|
|||||||
Qsmtp
|
Qsmtp
|
||||||
Qsts
|
Qsts
|
||||||
gmail
|
gmail
|
||||||
|
backupmx
|
||||||
|
noreply
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
* Patches change both the patchlevel and the release date. Snapshots have no
|
* Patches change both the patchlevel and the release date. Snapshots have no
|
||||||
* patchlevel; they change the release date only.
|
* patchlevel; they change the release date only.
|
||||||
*/
|
*/
|
||||||
#define MAIL_RELEASE_DATE "20241010"
|
#define MAIL_RELEASE_DATE "20241024"
|
||||||
#define MAIL_VERSION_NUMBER "3.10"
|
#define MAIL_VERSION_NUMBER "3.10"
|
||||||
|
|
||||||
#ifdef SNAPSHOT
|
#ifdef SNAPSHOT
|
||||||
|
@ -285,12 +285,17 @@ static void tls_policy_lookup_one(SMTP_TLS_POLICY *tls, int *site_level,
|
|||||||
/*
|
/*
|
||||||
* Errors in attributes may have security consequences, don't ignore
|
* Errors in attributes may have security consequences, don't ignore
|
||||||
* errors that can degrade security.
|
* errors that can degrade security.
|
||||||
|
*
|
||||||
|
* Caution: normalize whitespace, to neutralize line break etc. characters
|
||||||
|
* inside the value portion of { name = value }.
|
||||||
*/
|
*/
|
||||||
while ((tok = mystrtokq(&policy, CHARS_COMMA_SP, CHARS_BRACE)) != 0) {
|
while ((tok = mystrtokq(&policy, CHARS_COMMA_SP, CHARS_BRACE)) != 0) {
|
||||||
const char *err;
|
const char *err;
|
||||||
|
|
||||||
|
#define EXTPAR_OPT (EXTPAR_FLAG_STRIP | EXTPAR_FLAG_NORMAL_WS)
|
||||||
|
|
||||||
if ((tok[0] == CHARS_BRACE[0]
|
if ((tok[0] == CHARS_BRACE[0]
|
||||||
&& (err = free_me = extpar(&tok, CHARS_BRACE, EXTPAR_FLAG_STRIP)) != 0)
|
&& (err = free_me = extpar(&tok, CHARS_BRACE, EXTPAR_OPT)) != 0)
|
||||||
|| (err = split_nameval(tok, &name, &val)) != 0) {
|
|| (err = split_nameval(tok, &name, &val)) != 0) {
|
||||||
msg_warn("%s: malformed attribute/value pair \"%s\": %s",
|
msg_warn("%s: malformed attribute/value pair \"%s\": %s",
|
||||||
WHERE, tok, err);
|
WHERE, tok, err);
|
||||||
|
@ -2389,6 +2389,7 @@ static int mail_open_stream(SMTPD_STATE *state)
|
|||||||
", sasl_method=", state->sasl_method),
|
", sasl_method=", state->sasl_method),
|
||||||
PRINT2_OR_NULL(state->sasl_username,
|
PRINT2_OR_NULL(state->sasl_username,
|
||||||
", sasl_username=", state->sasl_username),
|
", sasl_username=", state->sasl_username),
|
||||||
|
/* This is safe because state->sasl_sender is xtext-encoded. */
|
||||||
PRINT2_OR_NULL(state->sasl_sender,
|
PRINT2_OR_NULL(state->sasl_sender,
|
||||||
", sasl_sender=", state->sasl_sender),
|
", sasl_sender=", state->sasl_sender),
|
||||||
#else
|
#else
|
||||||
|
@ -1016,6 +1016,15 @@ void log_whatsup(SMTPD_STATE *state, const char *whatsup,
|
|||||||
vstring_sprintf_append(buf, " proto=%s", state->protocol);
|
vstring_sprintf_append(buf, " proto=%s", state->protocol);
|
||||||
if (state->helo_name)
|
if (state->helo_name)
|
||||||
vstring_sprintf_append(buf, " helo=<%s>", state->helo_name);
|
vstring_sprintf_append(buf, " helo=<%s>", state->helo_name);
|
||||||
|
#ifdef USE_SASL_AUTH
|
||||||
|
if (state->sasl_method)
|
||||||
|
vstring_sprintf_append(buf, " sasl_method=%s", state->sasl_method);
|
||||||
|
if (state->sasl_username)
|
||||||
|
vstring_sprintf_append(buf, " sasl_username=%s", state->sasl_username);
|
||||||
|
/* This is safe because state->sasl_sender is xtext-encoded. */
|
||||||
|
if (state->sasl_sender)
|
||||||
|
vstring_sprintf_append(buf, " sasl_sender=%s", state->sasl_sender);
|
||||||
|
#endif
|
||||||
msg_info("%s", STR(buf));
|
msg_info("%s", STR(buf));
|
||||||
vstring_free(buf);
|
vstring_free(buf);
|
||||||
}
|
}
|
||||||
|
@ -46,7 +46,7 @@ SRCS = alldig.c allprint.c argv.c argv_split.c attr_clnt.c attr_print0.c \
|
|||||||
sane_strtol.c hash_fnv.c ldseed.c mkmap_cdb.c mkmap_db.c mkmap_dbm.c \
|
sane_strtol.c hash_fnv.c ldseed.c mkmap_cdb.c mkmap_db.c mkmap_dbm.c \
|
||||||
mkmap_fail.c mkmap_lmdb.c mkmap_open.c mkmap_sdbm.c inet_prefix_top.c \
|
mkmap_fail.c mkmap_lmdb.c mkmap_open.c mkmap_sdbm.c inet_prefix_top.c \
|
||||||
inet_addr_sizes.c quote_for_json.c mystrerror.c \
|
inet_addr_sizes.c quote_for_json.c mystrerror.c \
|
||||||
sane_sockaddr_to_hostaddr.c
|
sane_sockaddr_to_hostaddr.c normalize_ws.c
|
||||||
OBJS = alldig.o allprint.o argv.o argv_split.o attr_clnt.o attr_print0.o \
|
OBJS = alldig.o allprint.o argv.o argv_split.o attr_clnt.o attr_print0.o \
|
||||||
attr_print64.o attr_print_plain.o attr_scan0.o attr_scan64.o \
|
attr_print64.o attr_print_plain.o attr_scan0.o attr_scan64.o \
|
||||||
attr_scan_plain.o auto_clnt.o base64_code.o basename.o binhash.o \
|
attr_scan_plain.o auto_clnt.o base64_code.o basename.o binhash.o \
|
||||||
@ -93,7 +93,8 @@ OBJS = alldig.o allprint.o argv.o argv_split.o attr_clnt.o attr_print0.o \
|
|||||||
byte_mask.o known_tcp_ports.o argv_split_at.o dict_stream.o \
|
byte_mask.o known_tcp_ports.o argv_split_at.o dict_stream.o \
|
||||||
sane_strtol.o hash_fnv.o ldseed.o mkmap_db.o mkmap_dbm.o \
|
sane_strtol.o hash_fnv.o ldseed.o mkmap_db.o mkmap_dbm.o \
|
||||||
mkmap_fail.o mkmap_open.o inet_prefix_top.o inet_addr_sizes.o \
|
mkmap_fail.o mkmap_open.o inet_prefix_top.o inet_addr_sizes.o \
|
||||||
quote_for_json.o mystrerror.o sane_sockaddr_to_hostaddr.o
|
quote_for_json.o mystrerror.o sane_sockaddr_to_hostaddr.o \
|
||||||
|
normalize_ws.o
|
||||||
# MAP_OBJ is for maps that may be dynamically loaded with dynamicmaps.cf.
|
# MAP_OBJ is for maps that may be dynamically loaded with dynamicmaps.cf.
|
||||||
# When hard-linking these, makedefs sets NON_PLUGIN_MAP_OBJ=$(MAP_OBJ),
|
# When hard-linking these, makedefs sets NON_PLUGIN_MAP_OBJ=$(MAP_OBJ),
|
||||||
# otherwise it sets the PLUGIN_* macros.
|
# otherwise it sets the PLUGIN_* macros.
|
||||||
@ -147,7 +148,8 @@ TESTPROG= dict_open dup2_pass_on_exec events exec_command fifo_open \
|
|||||||
vstream timecmp dict_cache midna_domain casefold strcasecmp_utf8 \
|
vstream timecmp dict_cache midna_domain casefold strcasecmp_utf8 \
|
||||||
vbuf_print split_qnameval vstream msg_logger byte_mask \
|
vbuf_print split_qnameval vstream msg_logger byte_mask \
|
||||||
known_tcp_ports dict_stream find_inet binhash hash_fnv argv \
|
known_tcp_ports dict_stream find_inet binhash hash_fnv argv \
|
||||||
clean_env inet_prefix_top printable readlline quote_for_json
|
clean_env inet_prefix_top printable readlline quote_for_json \
|
||||||
|
normalize_ws
|
||||||
PLUGIN_MAP_SO = $(LIB_PREFIX)pcre$(LIB_SUFFIX) $(LIB_PREFIX)lmdb$(LIB_SUFFIX) \
|
PLUGIN_MAP_SO = $(LIB_PREFIX)pcre$(LIB_SUFFIX) $(LIB_PREFIX)lmdb$(LIB_SUFFIX) \
|
||||||
$(LIB_PREFIX)cdb$(LIB_SUFFIX) $(LIB_PREFIX)sdbm$(LIB_SUFFIX)
|
$(LIB_PREFIX)cdb$(LIB_SUFFIX) $(LIB_PREFIX)sdbm$(LIB_SUFFIX)
|
||||||
HTABLE_FIX = NORANDOMIZE=1
|
HTABLE_FIX = NORANDOMIZE=1
|
||||||
@ -611,6 +613,11 @@ quote_for_json: $(LIB)
|
|||||||
$(CC) $(CFLAGS) -DTEST -o $@ $@.c $(LIB) $(SYSLIBS)
|
$(CC) $(CFLAGS) -DTEST -o $@ $@.c $(LIB) $(SYSLIBS)
|
||||||
mv junk $@.o
|
mv junk $@.o
|
||||||
|
|
||||||
|
normalize_ws: $(LIB)
|
||||||
|
mv $@.o junk
|
||||||
|
$(CC) $(CFLAGS) -DTEST -o $@ $@.c $(LIB) $(SYSLIBS)
|
||||||
|
mv junk $@.o
|
||||||
|
|
||||||
tests: all valid_hostname_test mac_expand_test dict_test unescape_test \
|
tests: all valid_hostname_test mac_expand_test dict_test unescape_test \
|
||||||
hex_quote_test ctable_test inet_addr_list_test base64_code_test \
|
hex_quote_test ctable_test inet_addr_list_test base64_code_test \
|
||||||
attr_scan64_test attr_scan0_test host_port_test dict_tests \
|
attr_scan64_test attr_scan0_test host_port_test dict_tests \
|
||||||
@ -621,7 +628,8 @@ tests: all valid_hostname_test mac_expand_test dict_test unescape_test \
|
|||||||
miss_endif_regexp_test split_qnameval_test vstring_test \
|
miss_endif_regexp_test split_qnameval_test vstring_test \
|
||||||
vstream_test byte_mask_tests mystrtok_test known_tcp_ports_test \
|
vstream_test byte_mask_tests mystrtok_test known_tcp_ports_test \
|
||||||
binhash_test argv_test inet_prefix_top_test printable_test \
|
binhash_test argv_test inet_prefix_top_test printable_test \
|
||||||
valid_utf8_string_test readlline_test quote_for_json_test
|
valid_utf8_string_test readlline_test quote_for_json_test \
|
||||||
|
normalize_ws_test
|
||||||
|
|
||||||
dict_tests: all dict_test \
|
dict_tests: all dict_test \
|
||||||
dict_pcre_tests dict_cidr_test dict_thash_test dict_static_test \
|
dict_pcre_tests dict_cidr_test dict_thash_test dict_static_test \
|
||||||
@ -1098,6 +1106,9 @@ inet_prefix_top_test: inet_prefix_top
|
|||||||
quote_for_json_test: quote_for_json
|
quote_for_json_test: quote_for_json
|
||||||
$(SHLIB_ENV) ${VALGRIND} ./quote_for_json
|
$(SHLIB_ENV) ${VALGRIND} ./quote_for_json
|
||||||
|
|
||||||
|
normalize_ws_test: normalize_ws
|
||||||
|
$(SHLIB_ENV) ${VALGRIND} ./normalize_ws
|
||||||
|
|
||||||
depend: $(MAKES)
|
depend: $(MAKES)
|
||||||
(sed '1,/^# do not edit/!d' Makefile.in; \
|
(sed '1,/^# do not edit/!d' Makefile.in; \
|
||||||
set -e; for i in [a-z][a-z0-9]*.c; do \
|
set -e; for i in [a-z][a-z0-9]*.c; do \
|
||||||
@ -2495,6 +2506,16 @@ non_blocking.o: iostuff.h
|
|||||||
non_blocking.o: msg.h
|
non_blocking.o: msg.h
|
||||||
non_blocking.o: non_blocking.c
|
non_blocking.o: non_blocking.c
|
||||||
non_blocking.o: sys_defs.h
|
non_blocking.o: sys_defs.h
|
||||||
|
normalize_ws.o: check_arg.h
|
||||||
|
normalize_ws.o: msg.h
|
||||||
|
normalize_ws.o: msg_vstream.h
|
||||||
|
normalize_ws.o: mymalloc.h
|
||||||
|
normalize_ws.o: normalize_ws.c
|
||||||
|
normalize_ws.o: stringops.h
|
||||||
|
normalize_ws.o: sys_defs.h
|
||||||
|
normalize_ws.o: vbuf.h
|
||||||
|
normalize_ws.o: vstream.h
|
||||||
|
normalize_ws.o: vstring.h
|
||||||
nvtable.o: htable.h
|
nvtable.o: htable.h
|
||||||
nvtable.o: mymalloc.h
|
nvtable.o: mymalloc.h
|
||||||
nvtable.o: nvtable.c
|
nvtable.o: nvtable.c
|
||||||
|
@ -31,6 +31,10 @@
|
|||||||
/* .IP EXTPAR_FLAG_STRIP
|
/* .IP EXTPAR_FLAG_STRIP
|
||||||
/* Skip whitespace after the opening parenthesis, and trim
|
/* Skip whitespace after the opening parenthesis, and trim
|
||||||
/* whitespace before the closing parenthesis.
|
/* whitespace before the closing parenthesis.
|
||||||
|
/* .IP EXTPAR_FLAG_NORMAL_WS
|
||||||
|
/* Substitute SPACE for control characters (newline etc.) that
|
||||||
|
/* match isspace(). This neutralizes line break etc. characters in
|
||||||
|
/* the value portion of { name = value }.
|
||||||
/* .RE
|
/* .RE
|
||||||
/* DIAGNOSTICS
|
/* DIAGNOSTICS
|
||||||
/* In case of error the result value is a dynamically-allocated
|
/* In case of error the result value is a dynamically-allocated
|
||||||
@ -104,6 +108,8 @@ char *extpar(char **bp, const char *parens, int flags)
|
|||||||
while (ISSPACE(*cp))
|
while (ISSPACE(*cp))
|
||||||
cp++;
|
cp++;
|
||||||
}
|
}
|
||||||
|
if (flags & EXTPAR_FLAG_NORMAL_WS)
|
||||||
|
normalize_ws(cp);
|
||||||
*bp = cp;
|
*bp = cp;
|
||||||
return (err);
|
return (err);
|
||||||
}
|
}
|
||||||
|
144
postfix/src/util/normalize_ws.c
Normal file
144
postfix/src/util/normalize_ws.c
Normal file
@ -0,0 +1,144 @@
|
|||||||
|
/*++
|
||||||
|
/* NAME
|
||||||
|
/* normalize_ws 3
|
||||||
|
/* SUMMARY
|
||||||
|
/* neutralize isspace()-matching control characters
|
||||||
|
/* SYNOPSIS
|
||||||
|
/* #include <stringops.h>
|
||||||
|
/*
|
||||||
|
/* char *normalize_ws(char *str)
|
||||||
|
/* DESCRIPTION
|
||||||
|
/* normalize_ws() takes a null-terminated string and substitutes
|
||||||
|
/* ASCII SPACE for any ASCII control characters that match
|
||||||
|
/* isspace(). This neutralizes line break etc. characters in the
|
||||||
|
/* value portion of { name = value }. The function substitutes
|
||||||
|
/* bytes in place, and returns its str argument.
|
||||||
|
/*
|
||||||
|
/* This function requires that input is encoded in ASCII or UTF-8.
|
||||||
|
/* LICENSE
|
||||||
|
/* .ad
|
||||||
|
/* .fi
|
||||||
|
/* The Secure Mailer license must be distributed with this software.
|
||||||
|
/* AUTHOR(S)
|
||||||
|
/* Wietse Venema
|
||||||
|
/* porcupine.org
|
||||||
|
/*--*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* System library.
|
||||||
|
*/
|
||||||
|
#include <sys_defs.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Utility library.
|
||||||
|
*/
|
||||||
|
#include <msg.h>
|
||||||
|
#include <msg_vstream.h>
|
||||||
|
#include <mymalloc.h>
|
||||||
|
#include <stringops.h>
|
||||||
|
|
||||||
|
/* normalize_ws - replace isspace() members with space characters */
|
||||||
|
|
||||||
|
char *normalize_ws(char *str)
|
||||||
|
{
|
||||||
|
char *cp;
|
||||||
|
|
||||||
|
for (cp = str; *(cp += strcspn(cp, "\t\n\v\f\r")); *cp = ' ')
|
||||||
|
/* void */ ;
|
||||||
|
return (str);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef TEST
|
||||||
|
|
||||||
|
typedef struct TEST_CASE {
|
||||||
|
const char *label;
|
||||||
|
int (*action) (const struct TEST_CASE *);
|
||||||
|
const char *input;
|
||||||
|
const char *want;
|
||||||
|
} TEST_CASE;
|
||||||
|
|
||||||
|
#define PASS (0)
|
||||||
|
#define FAIL (1)
|
||||||
|
|
||||||
|
#define BUFLEN 2
|
||||||
|
|
||||||
|
/* if this test fails, isspace() may have changed */
|
||||||
|
|
||||||
|
static int normalizes_all_isspace_members(const TEST_CASE *unused)
|
||||||
|
{
|
||||||
|
int ch;
|
||||||
|
char input[BUFLEN];
|
||||||
|
char want[BUFLEN];
|
||||||
|
char *got;
|
||||||
|
|
||||||
|
for (ch = 0; ISASCII(ch); ch++) {
|
||||||
|
input[0] = ch;
|
||||||
|
input[1] = 0;
|
||||||
|
want[0] = ISSPACE(ch) ? ' ' : ch;
|
||||||
|
want[1] = 0;
|
||||||
|
got = normalize_ws(input);
|
||||||
|
if (got != input) {
|
||||||
|
msg_warn("got %p, want %p", got, input);
|
||||||
|
return (FAIL);
|
||||||
|
}
|
||||||
|
if (memcmp(got, want, BUFLEN) != 0) {
|
||||||
|
msg_warn("got '{0x%02x 0x%02x}', want '{0x%02x 0x%02x}",
|
||||||
|
got[0], got[1], want[0], want[1]);
|
||||||
|
return (FAIL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (PASS);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int test_normalize_ws(const TEST_CASE *tp)
|
||||||
|
{
|
||||||
|
char *input = mystrdup(tp->input);
|
||||||
|
char *got;
|
||||||
|
|
||||||
|
got = normalize_ws(input);
|
||||||
|
if (strcmp(got, tp->want) != 0) {
|
||||||
|
msg_warn("got '%s', want '%s'", got, tp->want);
|
||||||
|
return (FAIL);
|
||||||
|
}
|
||||||
|
myfree(input);
|
||||||
|
return (PASS);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const TEST_CASE test_cases[] = {
|
||||||
|
{"normalizes all isspace members", normalizes_all_isspace_members,},
|
||||||
|
{"normalizes_first", test_normalize_ws, "\tfoo", " foo",},
|
||||||
|
{"normalizes_middle", test_normalize_ws, "fo\to", "fo o",},
|
||||||
|
{"normalizes_last", test_normalize_ws, "foo\t", "foo ",},
|
||||||
|
{"normalizes_multiple", test_normalize_ws, "\tfo\to\t", " fo o ",},
|
||||||
|
{0,}
|
||||||
|
};
|
||||||
|
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
const TEST_CASE *tp;
|
||||||
|
int pass = 0;
|
||||||
|
int fail = 0;
|
||||||
|
|
||||||
|
msg_vstream_init(sane_basename((VSTRING *) 0, argv[0]), VSTREAM_ERR);
|
||||||
|
|
||||||
|
for (tp = test_cases; tp->label != 0; tp++) {
|
||||||
|
int test_failed;
|
||||||
|
|
||||||
|
msg_info("RUN %s", tp->label);
|
||||||
|
test_failed = tp->action(tp);
|
||||||
|
if (test_failed) {
|
||||||
|
msg_info("FAIL %s", tp->label);
|
||||||
|
fail++;
|
||||||
|
} else {
|
||||||
|
msg_info("PASS %s", tp->label);
|
||||||
|
pass++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
msg_info("PASS=%d FAIL=%d", pass, fail);
|
||||||
|
exit(fail != 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
@ -68,10 +68,12 @@ extern int strncasecmp_utf8x(int, const char *, const char *, ssize_t);
|
|||||||
extern char *quote_for_json(VSTRING *, const char *, ssize_t);
|
extern char *quote_for_json(VSTRING *, const char *, ssize_t);
|
||||||
extern char *quote_for_json_append(VSTRING *, const char *, ssize_t);
|
extern char *quote_for_json_append(VSTRING *, const char *, ssize_t);
|
||||||
extern const char *mystrerror(int);
|
extern const char *mystrerror(int);
|
||||||
|
extern char *normalize_ws(char *);
|
||||||
|
|
||||||
#define EXTPAR_FLAG_NONE (0)
|
#define EXTPAR_FLAG_NONE (0)
|
||||||
#define EXTPAR_FLAG_STRIP (1<<0) /* "{ text }" -> "text" */
|
#define EXTPAR_FLAG_STRIP (1<<0) /* "{ text }" -> "text" */
|
||||||
#define EXTPAR_FLAG_EXTRACT (1<<1) /* hint from caller's caller */
|
#define EXTPAR_FLAG_EXTRACT (1<<1) /* hint from caller's caller */
|
||||||
|
#define EXTPAR_FLAG_NORMAL_WS (1<<2) /* normalize 'isspace' members */
|
||||||
|
|
||||||
#define CASEF_FLAG_UTF8 (1<<0)
|
#define CASEF_FLAG_UTF8 (1<<0)
|
||||||
#define CASEF_FLAG_APPEND (1<<1)
|
#define CASEF_FLAG_APPEND (1<<1)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user