mirror of
https://github.com/vdukhovni/postfix
synced 2025-08-28 20:57:56 +00:00
postfix-2.11-20130405
This commit is contained in:
parent
46a1d9a44f
commit
030e4ddd54
@ -18410,3 +18410,24 @@ Apologies for any names omitted.
|
|||||||
|
|
||||||
Documentation: in smtpd.c, the comment that justifies the
|
Documentation: in smtpd.c, the comment that justifies the
|
||||||
454 reply for "TLS unavailable" cited the wrong RFC.
|
454 reply for "TLS unavailable" cited the wrong RFC.
|
||||||
|
|
||||||
|
20130404
|
||||||
|
|
||||||
|
Human factors: warning when a main.cf parameter has multiple
|
||||||
|
entries with different values. File: util/dict.c.
|
||||||
|
|
||||||
|
20130405
|
||||||
|
|
||||||
|
Feature: the recipient_delimiter parameter can now specify
|
||||||
|
a set of characters. A user name is now separated from its
|
||||||
|
address extension by the first character that matches the
|
||||||
|
recipient_delimiter set. Files: proto/postconf.proto,
|
||||||
|
src/global/mail_addr_find.c, src/global/mail_params.c,
|
||||||
|
src/global/split_addr.c, src/global/split_addr.h,
|
||||||
|
src/global/strip_addr.c, src/global/strip_addr.h,
|
||||||
|
src/global/strip_addr.ref, src/local/bounce_workaround.c,
|
||||||
|
src/local/local.c, src/local/local_expand.c, src/local/recipient.c,
|
||||||
|
src/local/resolve.c, src/oqmgr/qmgr_message.c, src/pipe/pipe.c,
|
||||||
|
src/qmgr/qmgr_message.c, src/smtpd/smtpd.c,
|
||||||
|
src/smtpd/smtpd_check.c, src/trivial-rewrite/transport.c,
|
||||||
|
src/trivial-rewrite/trivial-rewrite.c.
|
||||||
|
@ -14,6 +14,19 @@ specifies the release date of a stable release or snapshot release.
|
|||||||
If you upgrade from Postfix 2.9 or earlier, read RELEASE_NOTES-2.10
|
If you upgrade from Postfix 2.9 or earlier, read RELEASE_NOTES-2.10
|
||||||
before proceeding.
|
before proceeding.
|
||||||
|
|
||||||
|
Major changes with snapshot 20130405
|
||||||
|
====================================
|
||||||
|
|
||||||
|
The recipient_delimiter parameter can now specify a set of characters.
|
||||||
|
A user name is now separated from its address extension by the first
|
||||||
|
character that matches the recipient_delimiter set.
|
||||||
|
|
||||||
|
For example, specify "recipient_delimiter = +-" to support both the
|
||||||
|
Postfix-style "+" and the qmail-style "-" extension delimiter.
|
||||||
|
|
||||||
|
As before, this implementation recognizes one delimiter character
|
||||||
|
per email address, and one address extension per email address.
|
||||||
|
|
||||||
Major changes with snapshot 20130319
|
Major changes with snapshot 20130319
|
||||||
====================================
|
====================================
|
||||||
|
|
||||||
|
@ -608,8 +608,8 @@ LOCAL(8) LOCAL(8)
|
|||||||
tory.
|
tory.
|
||||||
|
|
||||||
<b><a href="postconf.5.html#recipient_delimiter">recipient_delimiter</a> (empty)</b>
|
<b><a href="postconf.5.html#recipient_delimiter">recipient_delimiter</a> (empty)</b>
|
||||||
The separator between user names and address exten-
|
The set of characters that can separate a user name
|
||||||
sions (user+foo).
|
from its address extension (user+foo).
|
||||||
|
|
||||||
<b><a href="postconf.5.html#require_home_directory">require_home_directory</a> (no)</b>
|
<b><a href="postconf.5.html#require_home_directory">require_home_directory</a> (no)</b>
|
||||||
Require that a <a href="local.8.html"><b>local</b>(8)</a> recipient's home directory
|
Require that a <a href="local.8.html"><b>local</b>(8)</a> recipient's home directory
|
||||||
|
@ -481,8 +481,8 @@ PIPE(8) PIPE(8)
|
|||||||
tory.
|
tory.
|
||||||
|
|
||||||
<b><a href="postconf.5.html#recipient_delimiter">recipient_delimiter</a> (empty)</b>
|
<b><a href="postconf.5.html#recipient_delimiter">recipient_delimiter</a> (empty)</b>
|
||||||
The separator between user names and address exten-
|
The set of characters that can separate a user name
|
||||||
sions (user+foo).
|
from its address extension (user+foo).
|
||||||
|
|
||||||
<b><a href="postconf.5.html#syslog_facility">syslog_facility</a> (mail)</b>
|
<b><a href="postconf.5.html#syslog_facility">syslog_facility</a> (mail)</b>
|
||||||
The syslog facility of Postfix logging.
|
The syslog facility of Postfix logging.
|
||||||
|
@ -1451,7 +1451,9 @@ with the character set that is specified with the
|
|||||||
|
|
||||||
<dt><b>$<a href="postconf.5.html#recipient_delimiter">recipient_delimiter</a></b></dt>
|
<dt><b>$<a href="postconf.5.html#recipient_delimiter">recipient_delimiter</a></b></dt>
|
||||||
|
|
||||||
<dd>The system-wide recipient address extension delimiter. </dd>
|
<dd>The address extension delimiter that was found in the recipient
|
||||||
|
address (Postfix 2.11 and later), or the system-wide recipient
|
||||||
|
address extension delimiter (Postfix 2.10 and earlier). </dd>
|
||||||
|
|
||||||
<dt><b>${name?value}</b></dt>
|
<dt><b>${name?value}</b></dt>
|
||||||
|
|
||||||
@ -3254,7 +3256,9 @@ filtered with the character set that is specified with the
|
|||||||
|
|
||||||
<dt><b>$<a href="postconf.5.html#recipient_delimiter">recipient_delimiter</a></b></dt>
|
<dt><b>$<a href="postconf.5.html#recipient_delimiter">recipient_delimiter</a></b></dt>
|
||||||
|
|
||||||
<dd>The system-wide recipient address extension delimiter. </dd>
|
<dd>The address extension delimiter that was found in the recipient
|
||||||
|
address (Postfix 2.11 and later), or the system-wide recipient
|
||||||
|
address extension delimiter (Postfix 2.10 and earlier). </dd>
|
||||||
|
|
||||||
<dt><b>${name?value}</b></dt>
|
<dt><b>${name?value}</b></dt>
|
||||||
|
|
||||||
@ -5308,7 +5312,9 @@ The following $name expansions are done on <a href="postconf.5.html#luser_relay"
|
|||||||
|
|
||||||
<dt><b>$<a href="postconf.5.html#recipient_delimiter">recipient_delimiter</a></b></dt>
|
<dt><b>$<a href="postconf.5.html#recipient_delimiter">recipient_delimiter</a></b></dt>
|
||||||
|
|
||||||
<dd>The system-wide recipient address extension delimiter. </dd>
|
<dd>The address extension delimiter that was found in the recipient
|
||||||
|
address (Postfix 2.11 and later), or the system-wide recipient
|
||||||
|
address extension delimiter (Postfix 2.10 and earlier). </dd>
|
||||||
|
|
||||||
<dt><b>$shell</b></dt>
|
<dt><b>$shell</b></dt>
|
||||||
|
|
||||||
@ -8498,22 +8504,53 @@ Example:
|
|||||||
<DT><b><a name="recipient_delimiter">recipient_delimiter</a>
|
<DT><b><a name="recipient_delimiter">recipient_delimiter</a>
|
||||||
(default: empty)</b></DT><DD>
|
(default: empty)</b></DT><DD>
|
||||||
|
|
||||||
<p>
|
<p> The set of characters that can separate a user name from its
|
||||||
The separator between user names and address extensions (user+foo).
|
address extension (user+foo). See <a href="canonical.5.html">canonical(5)</a>, <a href="local.8.html">local(8)</a>, <a href="relocated.5.html">relocated(5)</a>
|
||||||
See <a href="canonical.5.html">canonical(5)</a>, <a href="local.8.html">local(8)</a>, <a href="relocated.5.html">relocated(5)</a> and <a href="virtual.5.html">virtual(5)</a> for the
|
and <a href="virtual.5.html">virtual(5)</a> for the effects this has on aliases, canonical,
|
||||||
effects this has on aliases, canonical, virtual, relocated and
|
virtual, and relocated lookups. Basically, the software tries
|
||||||
on .forward file lookups. Basically, the software tries user+foo
|
user+foo and .forward+foo before trying user and .forward. </p>
|
||||||
and .forward+foo before trying user and .forward.
|
|
||||||
|
<p> This implementation recognizes one delimiter character per email
|
||||||
|
address, and one address extension per email address. </p>
|
||||||
|
|
||||||
|
<p> When the <a href="postconf.5.html#recipient_delimiter">recipient_delimiter</a> set contains multiple characters
|
||||||
|
(Postfix 2.11 and later), a user name is separated from its address
|
||||||
|
extension by the first character that matches the <a href="postconf.5.html#recipient_delimiter">recipient_delimiter</a>
|
||||||
|
set. </p>
|
||||||
|
|
||||||
|
<p> When used in <a href="postconf.5.html#forward_path">forward_path</a>, ${<a href="postconf.5.html#recipient_delimiter">recipient_delimiter</a>} is replaced
|
||||||
|
with the recipient delimiter that was found in the recipient email
|
||||||
|
address (Postfix 2.11 and later), or it is replaced with the <a href="postconf.5.html">main.cf</a>
|
||||||
|
<a href="postconf.5.html#recipient_delimiter">recipient_delimiter</a> parameter value (Postfix 2.10 and earlier).
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
<p> The <a href="postconf.5.html#recipient_delimiter">recipient_delimiter</a> is not applied to the mailer-daemon
|
||||||
|
address, the postmaster address, or the double-bounce address. With
|
||||||
|
the default "<a href="postconf.5.html#owner_request_special">owner_request_special</a> = yes" setting, the <a href="postconf.5.html#recipient_delimiter">recipient_delimiter</a>
|
||||||
|
is also not applied to addresses with the special "owner-" prefix
|
||||||
|
or the special "-request" suffix. </p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
Example:
|
Examples:
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<pre>
|
<pre>
|
||||||
|
# Handle Postfix-style extensions.
|
||||||
<a href="postconf.5.html#recipient_delimiter">recipient_delimiter</a> = +
|
<a href="postconf.5.html#recipient_delimiter">recipient_delimiter</a> = +
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
# Handle both Postfix and qmail extensions (Postfix 2.11 and later).
|
||||||
|
recipient_delimiters = +-
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
# Use .forward for mail without address extension, and for mail with
|
||||||
|
# an unrecognized address extension.
|
||||||
|
<a href="postconf.5.html#forward_path">forward_path</a> = $home/.forward${<a href="postconf.5.html#recipient_delimiter">recipient_delimiter</a>}${extension},
|
||||||
|
$home/.forward,
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
|
||||||
</DD>
|
</DD>
|
||||||
|
|
||||||
|
@ -1293,8 +1293,8 @@ SMTPD(8) SMTPD(8)
|
|||||||
tory.
|
tory.
|
||||||
|
|
||||||
<b><a href="postconf.5.html#recipient_delimiter">recipient_delimiter</a> (empty)</b>
|
<b><a href="postconf.5.html#recipient_delimiter">recipient_delimiter</a> (empty)</b>
|
||||||
The separator between user names and address exten-
|
The set of characters that can separate a user name
|
||||||
sions (user+foo).
|
from its address extension (user+foo).
|
||||||
|
|
||||||
<b><a href="postconf.5.html#smtpd_banner">smtpd_banner</a> ($<a href="postconf.5.html#myhostname">myhostname</a> ESMTP $<a href="postconf.5.html#mail_name">mail_name</a>)</b>
|
<b><a href="postconf.5.html#smtpd_banner">smtpd_banner</a> ($<a href="postconf.5.html#myhostname">myhostname</a> ESMTP $<a href="postconf.5.html#mail_name">mail_name</a>)</b>
|
||||||
The text that follows the 220 status code in the
|
The text that follows the 220 status code in the
|
||||||
|
@ -133,8 +133,8 @@ TRIVIAL-REWRITE(8) TRIVIAL-REWRITE(8)
|
|||||||
information.
|
information.
|
||||||
|
|
||||||
<b><a href="postconf.5.html#recipient_delimiter">recipient_delimiter</a> (empty)</b>
|
<b><a href="postconf.5.html#recipient_delimiter">recipient_delimiter</a> (empty)</b>
|
||||||
The separator between user names and address exten-
|
The set of characters that can separate a user name
|
||||||
sions (user+foo).
|
from its address extension (user+foo).
|
||||||
|
|
||||||
<b><a href="postconf.5.html#swap_bangpath">swap_bangpath</a> (yes)</b>
|
<b><a href="postconf.5.html#swap_bangpath">swap_bangpath</a> (yes)</b>
|
||||||
Enable the rewriting of "site!user" into
|
Enable the rewriting of "site!user" into
|
||||||
|
@ -835,7 +835,9 @@ The recipient domain.
|
|||||||
The entire recipient localpart.
|
The entire recipient localpart.
|
||||||
.br
|
.br
|
||||||
.IP "\fB$recipient_delimiter\fR"
|
.IP "\fB$recipient_delimiter\fR"
|
||||||
The system-wide recipient address extension delimiter.
|
The address extension delimiter that was found in the recipient
|
||||||
|
address (Postfix 2.11 and later), or the system-wide recipient
|
||||||
|
address extension delimiter (Postfix 2.10 and earlier).
|
||||||
.br
|
.br
|
||||||
.IP "\fB${name?value}\fR"
|
.IP "\fB${name?value}\fR"
|
||||||
Expands to \fIvalue\fR when \fI$name\fR is non-empty.
|
Expands to \fIvalue\fR when \fI$name\fR is non-empty.
|
||||||
@ -1919,7 +1921,9 @@ The recipient domain.
|
|||||||
The entire recipient localpart.
|
The entire recipient localpart.
|
||||||
.br
|
.br
|
||||||
.IP "\fB$recipient_delimiter\fR"
|
.IP "\fB$recipient_delimiter\fR"
|
||||||
The system-wide recipient address extension delimiter.
|
The address extension delimiter that was found in the recipient
|
||||||
|
address (Postfix 2.11 and later), or the system-wide recipient
|
||||||
|
address extension delimiter (Postfix 2.10 and earlier).
|
||||||
.br
|
.br
|
||||||
.IP "\fB${name?value}\fR"
|
.IP "\fB${name?value}\fR"
|
||||||
Expands to \fIvalue\fR when \fI$name\fR is non-empty.
|
Expands to \fIvalue\fR when \fI$name\fR is non-empty.
|
||||||
@ -3068,7 +3072,9 @@ The entire recipient address localpart.
|
|||||||
The full recipient address.
|
The full recipient address.
|
||||||
.br
|
.br
|
||||||
.IP "\fB$recipient_delimiter\fR"
|
.IP "\fB$recipient_delimiter\fR"
|
||||||
The system-wide recipient address extension delimiter.
|
The address extension delimiter that was found in the recipient
|
||||||
|
address (Postfix 2.11 and later), or the system-wide recipient
|
||||||
|
address extension delimiter (Postfix 2.10 and earlier).
|
||||||
.br
|
.br
|
||||||
.IP "\fB$shell\fR"
|
.IP "\fB$shell\fR"
|
||||||
The recipient's login shell.
|
The recipient's login shell.
|
||||||
@ -5095,21 +5101,61 @@ recipient_canonical_maps = hash:/etc/postfix/recipient_canonical
|
|||||||
.ad
|
.ad
|
||||||
.ft R
|
.ft R
|
||||||
.SH recipient_delimiter (default: empty)
|
.SH recipient_delimiter (default: empty)
|
||||||
The separator between user names and address extensions (user+foo).
|
The set of characters that can separate a user name from its
|
||||||
See \fBcanonical\fR(5), \fBlocal\fR(8), \fBrelocated\fR(5) and \fBvirtual\fR(5) for the
|
address extension (user+foo). See \fBcanonical\fR(5), \fBlocal\fR(8), \fBrelocated\fR(5)
|
||||||
effects this has on aliases, canonical, virtual, relocated and
|
and \fBvirtual\fR(5) for the effects this has on aliases, canonical,
|
||||||
on .forward file lookups. Basically, the software tries user+foo
|
virtual, and relocated lookups. Basically, the software tries
|
||||||
and .forward+foo before trying user and .forward.
|
user+foo and .forward+foo before trying user and .forward.
|
||||||
.PP
|
.PP
|
||||||
Example:
|
This implementation recognizes one delimiter character per email
|
||||||
|
address, and one address extension per email address.
|
||||||
|
.PP
|
||||||
|
When the recipient_delimiter set contains multiple characters
|
||||||
|
(Postfix 2.11 and later), a user name is separated from its address
|
||||||
|
extension by the first character that matches the recipient_delimiter
|
||||||
|
set.
|
||||||
|
.PP
|
||||||
|
When used in forward_path, ${recipient_delimiter} is replaced
|
||||||
|
with the recipient delimiter that was found in the recipient email
|
||||||
|
address (Postfix 2.11 and later), or it is replaced with the main.cf
|
||||||
|
recipient_delimiter parameter value (Postfix 2.10 and earlier).
|
||||||
|
.PP
|
||||||
|
The recipient_delimiter is not applied to the mailer-daemon
|
||||||
|
address, the postmaster address, or the double-bounce address. With
|
||||||
|
the default "owner_request_special = yes" setting, the recipient_delimiter
|
||||||
|
is also not applied to addresses with the special "owner-" prefix
|
||||||
|
or the special "-request" suffix.
|
||||||
|
.PP
|
||||||
|
Examples:
|
||||||
.PP
|
.PP
|
||||||
.nf
|
.nf
|
||||||
.na
|
.na
|
||||||
.ft C
|
.ft C
|
||||||
|
# Handle Postfix-style extensions.
|
||||||
recipient_delimiter = +
|
recipient_delimiter = +
|
||||||
.fi
|
.fi
|
||||||
.ad
|
.ad
|
||||||
.ft R
|
.ft R
|
||||||
|
.PP
|
||||||
|
.nf
|
||||||
|
.na
|
||||||
|
.ft C
|
||||||
|
# Handle both Postfix and qmail extensions (Postfix 2.11 and later).
|
||||||
|
recipient_delimiters = +-
|
||||||
|
.fi
|
||||||
|
.ad
|
||||||
|
.ft R
|
||||||
|
.PP
|
||||||
|
.nf
|
||||||
|
.na
|
||||||
|
.ft C
|
||||||
|
# Use .forward for mail without address extension, and for mail with
|
||||||
|
# an unrecognized address extension.
|
||||||
|
forward_path = $home/.forward${recipient_delimiter}${extension},
|
||||||
|
$home/.forward,
|
||||||
|
.fi
|
||||||
|
.ad
|
||||||
|
.ft R
|
||||||
.SH reject_code (default: 554)
|
.SH reject_code (default: 554)
|
||||||
The numerical Postfix SMTP server response code when a remote SMTP
|
The numerical Postfix SMTP server response code when a remote SMTP
|
||||||
client request is rejected by the "reject" restriction.
|
client request is rejected by the "reject" restriction.
|
||||||
|
@ -575,7 +575,8 @@ key to the lookup result.
|
|||||||
.IP "\fBqueue_directory (see 'postconf -d' output)\fR"
|
.IP "\fBqueue_directory (see 'postconf -d' output)\fR"
|
||||||
The location of the Postfix top-level queue directory.
|
The location of the Postfix top-level queue directory.
|
||||||
.IP "\fBrecipient_delimiter (empty)\fR"
|
.IP "\fBrecipient_delimiter (empty)\fR"
|
||||||
The separator between user names and address extensions (user+foo).
|
The set of characters that can separate a user name from its
|
||||||
|
address extension (user+foo).
|
||||||
.IP "\fBrequire_home_directory (no)\fR"
|
.IP "\fBrequire_home_directory (no)\fR"
|
||||||
Require that a \fBlocal\fR(8) recipient's home directory exists
|
Require that a \fBlocal\fR(8) recipient's home directory exists
|
||||||
before mail delivery is attempted.
|
before mail delivery is attempted.
|
||||||
|
@ -412,7 +412,8 @@ The process name of a Postfix command or daemon process.
|
|||||||
.IP "\fBqueue_directory (see 'postconf -d' output)\fR"
|
.IP "\fBqueue_directory (see 'postconf -d' output)\fR"
|
||||||
The location of the Postfix top-level queue directory.
|
The location of the Postfix top-level queue directory.
|
||||||
.IP "\fBrecipient_delimiter (empty)\fR"
|
.IP "\fBrecipient_delimiter (empty)\fR"
|
||||||
The separator between user names and address extensions (user+foo).
|
The set of characters that can separate a user name from its
|
||||||
|
address extension (user+foo).
|
||||||
.IP "\fBsyslog_facility (mail)\fR"
|
.IP "\fBsyslog_facility (mail)\fR"
|
||||||
The syslog facility of Postfix logging.
|
The syslog facility of Postfix logging.
|
||||||
.IP "\fBsyslog_name (see 'postconf -d' output)\fR"
|
.IP "\fBsyslog_name (see 'postconf -d' output)\fR"
|
||||||
|
@ -1012,7 +1012,8 @@ The process name of a Postfix command or daemon process.
|
|||||||
.IP "\fBqueue_directory (see 'postconf -d' output)\fR"
|
.IP "\fBqueue_directory (see 'postconf -d' output)\fR"
|
||||||
The location of the Postfix top-level queue directory.
|
The location of the Postfix top-level queue directory.
|
||||||
.IP "\fBrecipient_delimiter (empty)\fR"
|
.IP "\fBrecipient_delimiter (empty)\fR"
|
||||||
The separator between user names and address extensions (user+foo).
|
The set of characters that can separate a user name from its
|
||||||
|
address extension (user+foo).
|
||||||
.IP "\fBsmtpd_banner ($myhostname ESMTP $mail_name)\fR"
|
.IP "\fBsmtpd_banner ($myhostname ESMTP $mail_name)\fR"
|
||||||
The text that follows the 220 status code in the SMTP greeting
|
The text that follows the 220 status code in the SMTP greeting
|
||||||
banner.
|
banner.
|
||||||
|
@ -130,7 +130,8 @@ addresses without domain information.
|
|||||||
With locally submitted mail, append the string ".$mydomain" to
|
With locally submitted mail, append the string ".$mydomain" to
|
||||||
addresses that have no ".domain" information.
|
addresses that have no ".domain" information.
|
||||||
.IP "\fBrecipient_delimiter (empty)\fR"
|
.IP "\fBrecipient_delimiter (empty)\fR"
|
||||||
The separator between user names and address extensions (user+foo).
|
The set of characters that can separate a user name from its
|
||||||
|
address extension (user+foo).
|
||||||
.IP "\fBswap_bangpath (yes)\fR"
|
.IP "\fBswap_bangpath (yes)\fR"
|
||||||
Enable the rewriting of "site!user" into "user@site".
|
Enable the rewriting of "site!user" into "user@site".
|
||||||
.PP
|
.PP
|
||||||
|
@ -1609,7 +1609,9 @@ execution_directory_expansion_filter parameter. </p>
|
|||||||
|
|
||||||
<dt><b>$recipient_delimiter</b></dt>
|
<dt><b>$recipient_delimiter</b></dt>
|
||||||
|
|
||||||
<dd>The system-wide recipient address extension delimiter. </dd>
|
<dd>The address extension delimiter that was found in the recipient
|
||||||
|
address (Postfix 2.11 and later), or the system-wide recipient
|
||||||
|
address extension delimiter (Postfix 2.10 and earlier). </dd>
|
||||||
|
|
||||||
<dt><b>${name?value}</b></dt>
|
<dt><b>${name?value}</b></dt>
|
||||||
|
|
||||||
@ -1670,7 +1672,9 @@ forward_expansion_filter parameter. </p>
|
|||||||
|
|
||||||
<dt><b>$recipient_delimiter</b></dt>
|
<dt><b>$recipient_delimiter</b></dt>
|
||||||
|
|
||||||
<dd>The system-wide recipient address extension delimiter. </dd>
|
<dd>The address extension delimiter that was found in the recipient
|
||||||
|
address (Postfix 2.11 and later), or the system-wide recipient
|
||||||
|
address extension delimiter (Postfix 2.10 and earlier). </dd>
|
||||||
|
|
||||||
<dt><b>${name?value}</b></dt>
|
<dt><b>${name?value}</b></dt>
|
||||||
|
|
||||||
@ -2404,7 +2408,9 @@ The following $name expansions are done on luser_relay:
|
|||||||
|
|
||||||
<dt><b>$recipient_delimiter</b></dt>
|
<dt><b>$recipient_delimiter</b></dt>
|
||||||
|
|
||||||
<dd>The system-wide recipient address extension delimiter. </dd>
|
<dd>The address extension delimiter that was found in the recipient
|
||||||
|
address (Postfix 2.11 and later), or the system-wide recipient
|
||||||
|
address extension delimiter (Postfix 2.10 and earlier). </dd>
|
||||||
|
|
||||||
<dt><b>$shell</b></dt>
|
<dt><b>$shell</b></dt>
|
||||||
|
|
||||||
@ -3497,22 +3503,53 @@ recipient_canonical_maps = hash:/etc/postfix/recipient_canonical
|
|||||||
|
|
||||||
%PARAM recipient_delimiter
|
%PARAM recipient_delimiter
|
||||||
|
|
||||||
<p>
|
<p> The set of characters that can separate a user name from its
|
||||||
The separator between user names and address extensions (user+foo).
|
address extension (user+foo). See canonical(5), local(8), relocated(5)
|
||||||
See canonical(5), local(8), relocated(5) and virtual(5) for the
|
and virtual(5) for the effects this has on aliases, canonical,
|
||||||
effects this has on aliases, canonical, virtual, relocated and
|
virtual, and relocated lookups. Basically, the software tries
|
||||||
on .forward file lookups. Basically, the software tries user+foo
|
user+foo and .forward+foo before trying user and .forward. </p>
|
||||||
and .forward+foo before trying user and .forward.
|
|
||||||
|
<p> This implementation recognizes one delimiter character per email
|
||||||
|
address, and one address extension per email address. </p>
|
||||||
|
|
||||||
|
<p> When the recipient_delimiter set contains multiple characters
|
||||||
|
(Postfix 2.11 and later), a user name is separated from its address
|
||||||
|
extension by the first character that matches the recipient_delimiter
|
||||||
|
set. </p>
|
||||||
|
|
||||||
|
<p> When used in forward_path, ${recipient_delimiter} is replaced
|
||||||
|
with the recipient delimiter that was found in the recipient email
|
||||||
|
address (Postfix 2.11 and later), or it is replaced with the main.cf
|
||||||
|
recipient_delimiter parameter value (Postfix 2.10 and earlier).
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
<p> The recipient_delimiter is not applied to the mailer-daemon
|
||||||
|
address, the postmaster address, or the double-bounce address. With
|
||||||
|
the default "owner_request_special = yes" setting, the recipient_delimiter
|
||||||
|
is also not applied to addresses with the special "owner-" prefix
|
||||||
|
or the special "-request" suffix. </p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
Example:
|
Examples:
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<pre>
|
<pre>
|
||||||
|
# Handle Postfix-style extensions.
|
||||||
recipient_delimiter = +
|
recipient_delimiter = +
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
# Handle both Postfix and qmail extensions (Postfix 2.11 and later).
|
||||||
|
recipient_delimiters = +-
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
# Use .forward for mail without address extension, and for mail with
|
||||||
|
# an unrecognized address extension.
|
||||||
|
forward_path = $home/.forward${recipient_delimiter}${extension},
|
||||||
|
$home/.forward,
|
||||||
|
</pre>
|
||||||
|
|
||||||
%PARAM reject_code 554
|
%PARAM reject_code 554
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
|
@ -109,7 +109,7 @@ const char *mail_addr_find(MAPS *path, const char *address, char **extp)
|
|||||||
if (*var_rcpt_delim == 0) {
|
if (*var_rcpt_delim == 0) {
|
||||||
bare_key = saved_ext = 0;
|
bare_key = saved_ext = 0;
|
||||||
} else {
|
} else {
|
||||||
bare_key = strip_addr(full_key, &saved_ext, *var_rcpt_delim);
|
bare_key = strip_addr(full_key, &saved_ext, var_rcpt_delim);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -557,7 +557,7 @@ void mail_params_init()
|
|||||||
VAR_MAIL_VERSION, DEF_MAIL_VERSION, &var_mail_version, 1, 0,
|
VAR_MAIL_VERSION, DEF_MAIL_VERSION, &var_mail_version, 1, 0,
|
||||||
VAR_DB_TYPE, DEF_DB_TYPE, &var_db_type, 1, 0,
|
VAR_DB_TYPE, DEF_DB_TYPE, &var_db_type, 1, 0,
|
||||||
VAR_HASH_QUEUE_NAMES, DEF_HASH_QUEUE_NAMES, &var_hash_queue_names, 1, 0,
|
VAR_HASH_QUEUE_NAMES, DEF_HASH_QUEUE_NAMES, &var_hash_queue_names, 1, 0,
|
||||||
VAR_RCPT_DELIM, DEF_RCPT_DELIM, &var_rcpt_delim, 0, 1,
|
VAR_RCPT_DELIM, DEF_RCPT_DELIM, &var_rcpt_delim, 0, 0,
|
||||||
VAR_RELAY_DOMAINS, DEF_RELAY_DOMAINS, &var_relay_domains, 0, 0,
|
VAR_RELAY_DOMAINS, DEF_RELAY_DOMAINS, &var_relay_domains, 0, 0,
|
||||||
VAR_FFLUSH_DOMAINS, DEF_FFLUSH_DOMAINS, &var_fflush_domains, 0, 0,
|
VAR_FFLUSH_DOMAINS, DEF_FFLUSH_DOMAINS, &var_fflush_domains, 0, 0,
|
||||||
VAR_EXPORT_ENVIRON, DEF_EXPORT_ENVIRON, &var_export_environ, 0, 0,
|
VAR_EXPORT_ENVIRON, DEF_EXPORT_ENVIRON, &var_export_environ, 0, 0,
|
||||||
|
@ -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 "20130403"
|
#define MAIL_RELEASE_DATE "20130405"
|
||||||
#define MAIL_VERSION_NUMBER "2.11"
|
#define MAIL_VERSION_NUMBER "2.11"
|
||||||
|
|
||||||
#ifdef SNAPSHOT
|
#ifdef SNAPSHOT
|
||||||
|
@ -6,12 +6,12 @@
|
|||||||
/* SYNOPSIS
|
/* SYNOPSIS
|
||||||
/* #include <split_addr.h>
|
/* #include <split_addr.h>
|
||||||
/*
|
/*
|
||||||
/* char *split_addr(localpart, delimiter)
|
/* char *split_addr(localpart, delimiter_set)
|
||||||
/* char *localpart;
|
/* char *localpart;
|
||||||
/* int delimiter;
|
/* const char *delimiter_set;
|
||||||
/* DESCRIPTION
|
/* DESCRIPTION
|
||||||
/* split_addr() null-terminates \fIlocalpart\fR at the first
|
/* split_addr() null-terminates \fIlocalpart\fR at the first
|
||||||
/* occurrence of the \fIdelimiter\fR character found, and
|
/* occurrence of the \fIdelimiter\fR character(s) found, and
|
||||||
/* returns a pointer to the remainder.
|
/* returns a pointer to the remainder.
|
||||||
/*
|
/*
|
||||||
/* Reserved addresses are not split: postmaster, mailer-daemon,
|
/* Reserved addresses are not split: postmaster, mailer-daemon,
|
||||||
@ -50,7 +50,7 @@
|
|||||||
|
|
||||||
/* split_addr - split address with extreme prejudice */
|
/* split_addr - split address with extreme prejudice */
|
||||||
|
|
||||||
char *split_addr(char *localpart, int delimiter)
|
char *split_addr(char *localpart, const char *delimiter_set)
|
||||||
{
|
{
|
||||||
int len;
|
int len;
|
||||||
|
|
||||||
@ -67,7 +67,7 @@ char *split_addr(char *localpart, int delimiter)
|
|||||||
/*
|
/*
|
||||||
* Backwards compatibility: don't split owner-foo or foo-request.
|
* Backwards compatibility: don't split owner-foo or foo-request.
|
||||||
*/
|
*/
|
||||||
if (delimiter == '-' && var_ownreq_special != 0) {
|
if (strchr(delimiter_set, '-') != 0 && var_ownreq_special != 0) {
|
||||||
if (strncasecmp(localpart, "owner-", 6) == 0)
|
if (strncasecmp(localpart, "owner-", 6) == 0)
|
||||||
return (0);
|
return (0);
|
||||||
if ((len = strlen(localpart) - 8) > 0
|
if ((len = strlen(localpart) - 8) > 0
|
||||||
@ -79,5 +79,10 @@ char *split_addr(char *localpart, int delimiter)
|
|||||||
* Safe to split this address. Do not split the address if the result
|
* Safe to split this address. Do not split the address if the result
|
||||||
* would have a null localpart.
|
* would have a null localpart.
|
||||||
*/
|
*/
|
||||||
return (delimiter == *localpart ? 0 : split_at(localpart, delimiter));
|
if ((len = strcspn(localpart, delimiter_set)) == 0 || localpart[len] == 0) {
|
||||||
|
return (0);
|
||||||
|
} else {
|
||||||
|
localpart[len] = 0;
|
||||||
|
return (localpart + len + 1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
|
|
||||||
/* External interface. */
|
/* External interface. */
|
||||||
|
|
||||||
extern char *split_addr(char *, int);
|
extern char *split_addr(char *, const char *);
|
||||||
|
|
||||||
/* LICENSE
|
/* LICENSE
|
||||||
/* .ad
|
/* .ad
|
||||||
|
@ -6,10 +6,10 @@
|
|||||||
/* SYNOPSIS
|
/* SYNOPSIS
|
||||||
/* #include <strip_addr.h>
|
/* #include <strip_addr.h>
|
||||||
/*
|
/*
|
||||||
/* char *strip_addr(address, extension, delimiter)
|
/* char *strip_addr(address, extension, delimiter_set)
|
||||||
/* const char *address;
|
/* const char *address;
|
||||||
/* char **extension;
|
/* char **extension;
|
||||||
/* int delimiter;
|
/* const char *delimiter_set;
|
||||||
/* DESCRIPTION
|
/* DESCRIPTION
|
||||||
/* strip_addr() takes an address and either returns a null
|
/* strip_addr() takes an address and either returns a null
|
||||||
/* pointer when the address contains no address extension,
|
/* pointer when the address contains no address extension,
|
||||||
@ -25,8 +25,8 @@
|
|||||||
/* that had to be chopped off.
|
/* that had to be chopped off.
|
||||||
/* The copy includes the recipient address delimiter.
|
/* The copy includes the recipient address delimiter.
|
||||||
/* The caller is expected to pass the copy to myfree().
|
/* The caller is expected to pass the copy to myfree().
|
||||||
/* .IP delimiter
|
/* .IP delimiter_set
|
||||||
/* Recipient address delimiter.
|
/* Set of recipient address delimiter characters.
|
||||||
/* SEE ALSO
|
/* SEE ALSO
|
||||||
/* split_addr(3) strip extension from localpart
|
/* split_addr(3) strip extension from localpart
|
||||||
/* LICENSE
|
/* LICENSE
|
||||||
@ -56,7 +56,7 @@
|
|||||||
|
|
||||||
/* strip_addr - strip extension from address */
|
/* strip_addr - strip extension from address */
|
||||||
|
|
||||||
char *strip_addr(const char *full, char **extension, int delimiter)
|
char *strip_addr(const char *full, char **extension, const char *delimiter_set)
|
||||||
{
|
{
|
||||||
char *ratsign;
|
char *ratsign;
|
||||||
char *extent;
|
char *extent;
|
||||||
@ -66,16 +66,16 @@ char *strip_addr(const char *full, char **extension, int delimiter)
|
|||||||
/*
|
/*
|
||||||
* A quick test to eliminate inputs without delimiter anywhere.
|
* A quick test to eliminate inputs without delimiter anywhere.
|
||||||
*/
|
*/
|
||||||
if (delimiter == 0 || strchr(full, delimiter) == 0) {
|
if (*delimiter_set == 0 || full[strcspn(full, delimiter_set)] == 0) {
|
||||||
stripped = saved_ext = 0;
|
stripped = saved_ext = 0;
|
||||||
} else {
|
} else {
|
||||||
stripped = mystrdup(full);
|
stripped = mystrdup(full);
|
||||||
if ((ratsign = strrchr(stripped, '@')) != 0)
|
if ((ratsign = strrchr(stripped, '@')) != 0)
|
||||||
*ratsign = 0;
|
*ratsign = 0;
|
||||||
if ((extent = split_addr(stripped, delimiter)) != 0) {
|
if ((extent = split_addr(stripped, delimiter_set)) != 0) {
|
||||||
extent -= 1;
|
extent -= 1;
|
||||||
if (extension) {
|
if (extension) {
|
||||||
*extent = delimiter;
|
*extent = full[strlen(stripped)];
|
||||||
saved_ext = mystrdup(extent);
|
saved_ext = mystrdup(extent);
|
||||||
*extent = 0;
|
*extent = 0;
|
||||||
} else
|
} else
|
||||||
@ -105,17 +105,19 @@ int main(int unused_argc, char **unused_argv)
|
|||||||
{
|
{
|
||||||
char *extension;
|
char *extension;
|
||||||
char *stripped;
|
char *stripped;
|
||||||
int delim = '-';
|
char* delim = "+-";
|
||||||
|
|
||||||
|
#define NO_DELIM ""
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Incredible. This function takes only three arguments, and the tests
|
* Incredible. This function takes only three arguments, and the tests
|
||||||
* already take more lines of code than the code being tested.
|
* already take more lines of code than the code being tested.
|
||||||
*/
|
*/
|
||||||
stripped = strip_addr("foo", (char **) 0, 0);
|
stripped = strip_addr("foo", (char **) 0, NO_DELIM);
|
||||||
if (stripped != 0)
|
if (stripped != 0)
|
||||||
msg_panic("strip_addr botch 1");
|
msg_panic("strip_addr botch 1");
|
||||||
|
|
||||||
stripped = strip_addr("foo", &extension, 0);
|
stripped = strip_addr("foo", &extension, NO_DELIM);
|
||||||
if (stripped != 0)
|
if (stripped != 0)
|
||||||
msg_panic("strip_addr botch 2");
|
msg_panic("strip_addr botch 2");
|
||||||
if (extension != 0)
|
if (extension != 0)
|
||||||
@ -131,11 +133,11 @@ int main(int unused_argc, char **unused_argv)
|
|||||||
if (extension != 0)
|
if (extension != 0)
|
||||||
msg_panic("strip_addr botch 6");
|
msg_panic("strip_addr botch 6");
|
||||||
|
|
||||||
stripped = strip_addr("foo@bar", (char **) 0, 0);
|
stripped = strip_addr("foo@bar", (char **) 0, NO_DELIM);
|
||||||
if (stripped != 0)
|
if (stripped != 0)
|
||||||
msg_panic("strip_addr botch 7");
|
msg_panic("strip_addr botch 7");
|
||||||
|
|
||||||
stripped = strip_addr("foo@bar", &extension, 0);
|
stripped = strip_addr("foo@bar", &extension, NO_DELIM);
|
||||||
if (stripped != 0)
|
if (stripped != 0)
|
||||||
msg_panic("strip_addr botch 8");
|
msg_panic("strip_addr botch 8");
|
||||||
if (extension != 0)
|
if (extension != 0)
|
||||||
@ -151,11 +153,11 @@ int main(int unused_argc, char **unused_argv)
|
|||||||
if (extension != 0)
|
if (extension != 0)
|
||||||
msg_panic("strip_addr botch 12");
|
msg_panic("strip_addr botch 12");
|
||||||
|
|
||||||
stripped = strip_addr("foo-ext", (char **) 0, 0);
|
stripped = strip_addr("foo-ext", (char **) 0, NO_DELIM);
|
||||||
if (stripped != 0)
|
if (stripped != 0)
|
||||||
msg_panic("strip_addr botch 13");
|
msg_panic("strip_addr botch 13");
|
||||||
|
|
||||||
stripped = strip_addr("foo-ext", &extension, 0);
|
stripped = strip_addr("foo-ext", &extension, NO_DELIM);
|
||||||
if (stripped != 0)
|
if (stripped != 0)
|
||||||
msg_panic("strip_addr botch 14");
|
msg_panic("strip_addr botch 14");
|
||||||
if (extension != 0)
|
if (extension != 0)
|
||||||
@ -178,11 +180,11 @@ int main(int unused_argc, char **unused_argv)
|
|||||||
myfree(stripped);
|
myfree(stripped);
|
||||||
myfree(extension);
|
myfree(extension);
|
||||||
|
|
||||||
stripped = strip_addr("foo-ext@bar", (char **) 0, 0);
|
stripped = strip_addr("foo-ext@bar", (char **) 0, NO_DELIM);
|
||||||
if (stripped != 0)
|
if (stripped != 0)
|
||||||
msg_panic("strip_addr botch 19");
|
msg_panic("strip_addr botch 19");
|
||||||
|
|
||||||
stripped = strip_addr("foo-ext@bar", &extension, 0);
|
stripped = strip_addr("foo-ext@bar", &extension, NO_DELIM);
|
||||||
if (stripped != 0)
|
if (stripped != 0)
|
||||||
msg_panic("strip_addr botch 20");
|
msg_panic("strip_addr botch 20");
|
||||||
if (extension != 0)
|
if (extension != 0)
|
||||||
@ -205,6 +207,16 @@ int main(int unused_argc, char **unused_argv)
|
|||||||
myfree(stripped);
|
myfree(stripped);
|
||||||
myfree(extension);
|
myfree(extension);
|
||||||
|
|
||||||
|
stripped = strip_addr("foo+ext@bar", &extension, delim);
|
||||||
|
if (stripped == 0)
|
||||||
|
msg_panic("strip_addr botch 25");
|
||||||
|
if (extension == 0)
|
||||||
|
msg_panic("strip_addr botch 26");
|
||||||
|
msg_info("wanted: foo+ext@bar -> %s %s", "foo@bar", "+ext");
|
||||||
|
msg_info("strip_addr foo+ext@bar -> %s %s", stripped, extension);
|
||||||
|
myfree(stripped);
|
||||||
|
myfree(extension);
|
||||||
|
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
|
|
||||||
/* External interface. */
|
/* External interface. */
|
||||||
|
|
||||||
extern char *strip_addr(const char *, char **, int);
|
extern char *strip_addr(const char *, char **, const char *);
|
||||||
|
|
||||||
/* LICENSE
|
/* LICENSE
|
||||||
/* .ad
|
/* .ad
|
||||||
|
@ -6,3 +6,5 @@ unknown: wanted: foo-ext@bar -> foo@bar
|
|||||||
unknown: strip_addr foo-ext@bar -> foo@bar
|
unknown: strip_addr foo-ext@bar -> foo@bar
|
||||||
unknown: wanted: foo-ext@bar -> foo@bar -ext
|
unknown: wanted: foo-ext@bar -> foo@bar -ext
|
||||||
unknown: strip_addr foo-ext@bar -> foo@bar -ext
|
unknown: strip_addr foo-ext@bar -> foo@bar -ext
|
||||||
|
unknown: wanted: foo+ext@bar -> foo@bar +ext
|
||||||
|
unknown: strip_addr foo+ext@bar -> foo@bar +ext
|
||||||
|
@ -109,7 +109,7 @@ int bounce_workaround(LOCAL_STATE state)
|
|||||||
if (alias_maps->error == 0 && owner_expansion == 0
|
if (alias_maps->error == 0 && owner_expansion == 0
|
||||||
&& (stripped_recipient = strip_addr(state.msg_attr.rcpt.address,
|
&& (stripped_recipient = strip_addr(state.msg_attr.rcpt.address,
|
||||||
(char **) 0,
|
(char **) 0,
|
||||||
*var_rcpt_delim)) != 0) {
|
var_rcpt_delim)) != 0) {
|
||||||
myfree(owner_alias);
|
myfree(owner_alias);
|
||||||
FIND_OWNER(owner_alias, owner_expansion, stripped_recipient);
|
FIND_OWNER(owner_alias, owner_expansion, stripped_recipient);
|
||||||
myfree(stripped_recipient);
|
myfree(stripped_recipient);
|
||||||
|
@ -531,7 +531,8 @@
|
|||||||
/* .IP "\fBqueue_directory (see 'postconf -d' output)\fR"
|
/* .IP "\fBqueue_directory (see 'postconf -d' output)\fR"
|
||||||
/* The location of the Postfix top-level queue directory.
|
/* The location of the Postfix top-level queue directory.
|
||||||
/* .IP "\fBrecipient_delimiter (empty)\fR"
|
/* .IP "\fBrecipient_delimiter (empty)\fR"
|
||||||
/* The separator between user names and address extensions (user+foo).
|
/* The set of characters that can separate a user name from its
|
||||||
|
/* address extension (user+foo).
|
||||||
/* .IP "\fBrequire_home_directory (no)\fR"
|
/* .IP "\fBrequire_home_directory (no)\fR"
|
||||||
/* Require that a \fBlocal\fR(8) recipient's home directory exists
|
/* Require that a \fBlocal\fR(8) recipient's home directory exists
|
||||||
/* before mail delivery is attempted.
|
/* before mail delivery is attempted.
|
||||||
|
@ -113,6 +113,7 @@ typedef struct {
|
|||||||
static const char *local_expand_lookup(const char *name, int mode, char *ptr)
|
static const char *local_expand_lookup(const char *name, int mode, char *ptr)
|
||||||
{
|
{
|
||||||
LOCAL_EXP *local = (LOCAL_EXP *) ptr;
|
LOCAL_EXP *local = (LOCAL_EXP *) ptr;
|
||||||
|
static char rcpt_delim[2];
|
||||||
|
|
||||||
#define STREQ(x,y) (*(x) == *(y) && strcmp((x), (y)) == 0)
|
#define STREQ(x,y) (*(x) == *(y) && strcmp((x), (y)) == 0)
|
||||||
|
|
||||||
@ -135,7 +136,10 @@ static const char *local_expand_lookup(const char *name, int mode, char *ptr)
|
|||||||
local->status |= LOCAL_EXP_EXTENSION_MATCHED;
|
local->status |= LOCAL_EXP_EXTENSION_MATCHED;
|
||||||
return (local->state->msg_attr.extension);
|
return (local->state->msg_attr.extension);
|
||||||
} else if (STREQ(name, "recipient_delimiter")) {
|
} else if (STREQ(name, "recipient_delimiter")) {
|
||||||
return (*var_rcpt_delim ? var_rcpt_delim : 0);
|
rcpt_delim[0] =
|
||||||
|
local->state->msg_attr.local[strlen(local->state->msg_attr.user)];
|
||||||
|
rcpt_delim[1] = 0;
|
||||||
|
return (rcpt_delim[0] ? rcpt_delim : 0);
|
||||||
#if 0
|
#if 0
|
||||||
} else if (STREQ(name, "client_hostname")) {
|
} else if (STREQ(name, "client_hostname")) {
|
||||||
return (local->state->msg_attr.request->client_name);
|
return (local->state->msg_attr.request->client_name);
|
||||||
|
@ -270,7 +270,7 @@ int deliver_recipient(LOCAL_STATE state, USER_ATTR usr_attr)
|
|||||||
state.msg_attr.user = mystrdup(state.msg_attr.local);
|
state.msg_attr.user = mystrdup(state.msg_attr.local);
|
||||||
if (*var_rcpt_delim) {
|
if (*var_rcpt_delim) {
|
||||||
state.msg_attr.extension =
|
state.msg_attr.extension =
|
||||||
split_addr(state.msg_attr.user, *var_rcpt_delim);
|
split_addr(state.msg_attr.user, var_rcpt_delim);
|
||||||
if (state.msg_attr.extension && strchr(state.msg_attr.extension, '/')) {
|
if (state.msg_attr.extension && strchr(state.msg_attr.extension, '/')) {
|
||||||
msg_warn("%s: address with illegal extension: %s",
|
msg_warn("%s: address with illegal extension: %s",
|
||||||
state.msg_attr.queue_id, state.msg_attr.local);
|
state.msg_attr.queue_id, state.msg_attr.local);
|
||||||
|
@ -90,6 +90,7 @@ int deliver_resolve_tree(LOCAL_STATE state, USER_ATTR usr_attr, TOK822 *addr
|
|||||||
int status;
|
int status;
|
||||||
ssize_t ext_len;
|
ssize_t ext_len;
|
||||||
char *ratsign;
|
char *ratsign;
|
||||||
|
int rcpt_delim;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Make verbose logging easier to understand.
|
* Make verbose logging easier to understand.
|
||||||
@ -130,8 +131,9 @@ int deliver_resolve_tree(LOCAL_STATE state, USER_ATTR usr_attr, TOK822 *addr
|
|||||||
* Splice in the optional unmatched address extension.
|
* Splice in the optional unmatched address extension.
|
||||||
*/
|
*/
|
||||||
if (state.msg_attr.unmatched) {
|
if (state.msg_attr.unmatched) {
|
||||||
|
rcpt_delim = state.msg_attr.local[strlen(state.msg_attr.user)];
|
||||||
if ((ratsign = strrchr(STR(reply.recipient), '@')) == 0) {
|
if ((ratsign = strrchr(STR(reply.recipient), '@')) == 0) {
|
||||||
VSTRING_ADDCH(reply.recipient, *var_rcpt_delim);
|
VSTRING_ADDCH(reply.recipient, rcpt_delim);
|
||||||
vstring_strcat(reply.recipient, state.msg_attr.unmatched);
|
vstring_strcat(reply.recipient, state.msg_attr.unmatched);
|
||||||
} else {
|
} else {
|
||||||
ext_len = strlen(state.msg_attr.unmatched);
|
ext_len = strlen(state.msg_attr.unmatched);
|
||||||
@ -139,7 +141,7 @@ int deliver_resolve_tree(LOCAL_STATE state, USER_ATTR usr_attr, TOK822 *addr
|
|||||||
if ((ratsign = strrchr(STR(reply.recipient), '@')) == 0)
|
if ((ratsign = strrchr(STR(reply.recipient), '@')) == 0)
|
||||||
msg_panic("%s: recipient @ botch", myname);
|
msg_panic("%s: recipient @ botch", myname);
|
||||||
memmove(ratsign + ext_len + 1, ratsign, strlen(ratsign) + 1);
|
memmove(ratsign + ext_len + 1, ratsign, strlen(ratsign) + 1);
|
||||||
*ratsign = *var_rcpt_delim;
|
*ratsign = rcpt_delim;
|
||||||
memcpy(ratsign + 1, state.msg_attr.unmatched, ext_len);
|
memcpy(ratsign + 1, state.msg_attr.unmatched, ext_len);
|
||||||
VSTRING_SKIP(reply.recipient);
|
VSTRING_SKIP(reply.recipient);
|
||||||
}
|
}
|
||||||
|
@ -1175,7 +1175,7 @@ static void qmgr_message_resolve(QMGR_MESSAGE *message)
|
|||||||
: strlen(STR(reply.recipient)));
|
: strlen(STR(reply.recipient)));
|
||||||
vstring_strncpy(queue_name, STR(reply.recipient), len);
|
vstring_strncpy(queue_name, STR(reply.recipient), len);
|
||||||
/* Remove the address extension from the recipient localpart. */
|
/* Remove the address extension from the recipient localpart. */
|
||||||
if (*var_rcpt_delim && split_addr(STR(queue_name), *var_rcpt_delim))
|
if (*var_rcpt_delim && split_addr(STR(queue_name), var_rcpt_delim))
|
||||||
vstring_truncate(queue_name, strlen(STR(queue_name)));
|
vstring_truncate(queue_name, strlen(STR(queue_name)));
|
||||||
/* Assume the recipient domain is equivalent to nexthop. */
|
/* Assume the recipient domain is equivalent to nexthop. */
|
||||||
vstring_sprintf_append(queue_name, "@%s", STR(reply.nexthop));
|
vstring_sprintf_append(queue_name, "@%s", STR(reply.nexthop));
|
||||||
|
@ -390,7 +390,8 @@
|
|||||||
/* .IP "\fBqueue_directory (see 'postconf -d' output)\fR"
|
/* .IP "\fBqueue_directory (see 'postconf -d' output)\fR"
|
||||||
/* The location of the Postfix top-level queue directory.
|
/* The location of the Postfix top-level queue directory.
|
||||||
/* .IP "\fBrecipient_delimiter (empty)\fR"
|
/* .IP "\fBrecipient_delimiter (empty)\fR"
|
||||||
/* The separator between user names and address extensions (user+foo).
|
/* The set of characters that can separate a user name from its
|
||||||
|
/* address extension (user+foo).
|
||||||
/* .IP "\fBsyslog_facility (mail)\fR"
|
/* .IP "\fBsyslog_facility (mail)\fR"
|
||||||
/* The syslog facility of Postfix logging.
|
/* The syslog facility of Postfix logging.
|
||||||
/* .IP "\fBsyslog_name (see 'postconf -d' output)\fR"
|
/* .IP "\fBsyslog_name (see 'postconf -d' output)\fR"
|
||||||
@ -717,7 +718,7 @@ static ARGV *expand_argv(const char *service, char **argv,
|
|||||||
msg_warn("no @ in recipient address: %s",
|
msg_warn("no @ in recipient address: %s",
|
||||||
rcpt_list->info[i].address);
|
rcpt_list->info[i].address);
|
||||||
if (*var_rcpt_delim)
|
if (*var_rcpt_delim)
|
||||||
split_addr(STR(buf), *var_rcpt_delim);
|
split_addr(STR(buf), var_rcpt_delim);
|
||||||
if (*STR(buf) == 0)
|
if (*STR(buf) == 0)
|
||||||
continue;
|
continue;
|
||||||
dict_update(PIPE_DICT_TABLE, PIPE_DICT_USER, STR(buf));
|
dict_update(PIPE_DICT_TABLE, PIPE_DICT_USER, STR(buf));
|
||||||
@ -735,7 +736,7 @@ static ARGV *expand_argv(const char *service, char **argv,
|
|||||||
msg_warn("no @ in recipient address: %s",
|
msg_warn("no @ in recipient address: %s",
|
||||||
rcpt_list->info[i].address);
|
rcpt_list->info[i].address);
|
||||||
if (*var_rcpt_delim == 0
|
if (*var_rcpt_delim == 0
|
||||||
|| (ext = split_addr(STR(buf), *var_rcpt_delim)) == 0)
|
|| (ext = split_addr(STR(buf), var_rcpt_delim)) == 0)
|
||||||
ext = ""; /* insert null arg */
|
ext = ""; /* insert null arg */
|
||||||
dict_update(PIPE_DICT_TABLE, PIPE_DICT_EXTENSION, ext);
|
dict_update(PIPE_DICT_TABLE, PIPE_DICT_EXTENSION, ext);
|
||||||
}
|
}
|
||||||
|
@ -1234,7 +1234,7 @@ static void qmgr_message_resolve(QMGR_MESSAGE *message)
|
|||||||
: strlen(STR(reply.recipient)));
|
: strlen(STR(reply.recipient)));
|
||||||
vstring_strncpy(queue_name, STR(reply.recipient), len);
|
vstring_strncpy(queue_name, STR(reply.recipient), len);
|
||||||
/* Remove the address extension from the recipient localpart. */
|
/* Remove the address extension from the recipient localpart. */
|
||||||
if (*var_rcpt_delim && split_addr(STR(queue_name), *var_rcpt_delim))
|
if (*var_rcpt_delim && split_addr(STR(queue_name), var_rcpt_delim))
|
||||||
vstring_truncate(queue_name, strlen(STR(queue_name)));
|
vstring_truncate(queue_name, strlen(STR(queue_name)));
|
||||||
/* Assume the recipient domain is equivalent to nexthop. */
|
/* Assume the recipient domain is equivalent to nexthop. */
|
||||||
vstring_sprintf_append(queue_name, "@%s", STR(reply.nexthop));
|
vstring_sprintf_append(queue_name, "@%s", STR(reply.nexthop));
|
||||||
|
@ -956,7 +956,8 @@
|
|||||||
/* .IP "\fBqueue_directory (see 'postconf -d' output)\fR"
|
/* .IP "\fBqueue_directory (see 'postconf -d' output)\fR"
|
||||||
/* The location of the Postfix top-level queue directory.
|
/* The location of the Postfix top-level queue directory.
|
||||||
/* .IP "\fBrecipient_delimiter (empty)\fR"
|
/* .IP "\fBrecipient_delimiter (empty)\fR"
|
||||||
/* The separator between user names and address extensions (user+foo).
|
/* The set of characters that can separate a user name from its
|
||||||
|
/* address extension (user+foo).
|
||||||
/* .IP "\fBsmtpd_banner ($myhostname ESMTP $mail_name)\fR"
|
/* .IP "\fBsmtpd_banner ($myhostname ESMTP $mail_name)\fR"
|
||||||
/* The text that follows the 220 status code in the SMTP greeting
|
/* The text that follows the 220 status code in the SMTP greeting
|
||||||
/* banner.
|
/* banner.
|
||||||
|
@ -2866,7 +2866,7 @@ static int check_mail_access(SMTPD_STATE *state, const char *table,
|
|||||||
if (*var_rcpt_delim == 0) {
|
if (*var_rcpt_delim == 0) {
|
||||||
bare_addr = 0;
|
bare_addr = 0;
|
||||||
} else {
|
} else {
|
||||||
bare_addr = strip_addr(addr, (char **) 0, *var_rcpt_delim);
|
bare_addr = strip_addr(addr, (char **) 0, var_rcpt_delim);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define CHECK_MAIL_ACCESS_RETURN(x) \
|
#define CHECK_MAIL_ACCESS_RETURN(x) \
|
||||||
|
@ -286,7 +286,7 @@ int transport_lookup(TRANSPORT_INFO *tp, const char *addr,
|
|||||||
* partial lookup keys with regular expressions.
|
* partial lookup keys with regular expressions.
|
||||||
*/
|
*/
|
||||||
if ((stripped_addr = strip_addr(addr, DISCARD_EXTENSION,
|
if ((stripped_addr = strip_addr(addr, DISCARD_EXTENSION,
|
||||||
*var_rcpt_delim)) != 0) {
|
var_rcpt_delim)) != 0) {
|
||||||
found = find_transport_entry(tp, stripped_addr, rcpt_domain, PARTIAL,
|
found = find_transport_entry(tp, stripped_addr, rcpt_domain, PARTIAL,
|
||||||
channel, nexthop);
|
channel, nexthop);
|
||||||
|
|
||||||
|
@ -110,7 +110,8 @@
|
|||||||
/* With locally submitted mail, append the string ".$mydomain" to
|
/* With locally submitted mail, append the string ".$mydomain" to
|
||||||
/* addresses that have no ".domain" information.
|
/* addresses that have no ".domain" information.
|
||||||
/* .IP "\fBrecipient_delimiter (empty)\fR"
|
/* .IP "\fBrecipient_delimiter (empty)\fR"
|
||||||
/* The separator between user names and address extensions (user+foo).
|
/* The set of characters that can separate a user name from its
|
||||||
|
/* address extension (user+foo).
|
||||||
/* .IP "\fBswap_bangpath (yes)\fR"
|
/* .IP "\fBswap_bangpath (yes)\fR"
|
||||||
/* Enable the rewriting of "site!user" into "user@site".
|
/* Enable the rewriting of "site!user" into "user@site".
|
||||||
/* .PP
|
/* .PP
|
||||||
|
@ -431,6 +431,7 @@ void dict_load_fp(const char *dict_name, VSTREAM *fp)
|
|||||||
VSTRING *buf;
|
VSTRING *buf;
|
||||||
char *member;
|
char *member;
|
||||||
char *val;
|
char *val;
|
||||||
|
const char *old;
|
||||||
int old_lineno;
|
int old_lineno;
|
||||||
int lineno;
|
int lineno;
|
||||||
const char *err;
|
const char *err;
|
||||||
@ -455,6 +456,10 @@ void dict_load_fp(const char *dict_name, VSTREAM *fp)
|
|||||||
err, STR(buf));
|
err, STR(buf));
|
||||||
if (msg_verbose > 1)
|
if (msg_verbose > 1)
|
||||||
msg_info("%s: %s = %s", myname, member, val);
|
msg_info("%s: %s = %s", myname, member, val);
|
||||||
|
if ((old = dict->lookup(dict, member)) != 0
|
||||||
|
&& strcmp(old, val) != 0)
|
||||||
|
msg_warn("%s, line %d: overriding earlier entry: %s=%s",
|
||||||
|
VSTREAM_PATH(fp), lineno, member, old);
|
||||||
if (dict->update(dict, member, val) != 0)
|
if (dict->update(dict, member, val) != 0)
|
||||||
msg_fatal("%s, line %d: unable to update %s:%s",
|
msg_fatal("%s, line %d: unable to update %s:%s",
|
||||||
VSTREAM_PATH(fp), lineno, dict->type, dict->name);
|
VSTREAM_PATH(fp), lineno, dict->type, dict->name);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user