-TREC_TYPE_NAME
-TRESOLVE_REPLY
-TRESPONSE
+-TREST_TABLE
-TSCAN_DIR
-TSCAN_INFO
-TSCAN_OBJ
Bugfix: postmap/postalias queries ignored the -f flag.
Reported by Hamish Marson.
-20011215-6
-
- Safety: config file comments no longer span multiple lines
- when the next line starts with whitespace; a comment that
- is preceded by whitespace does not break multi-line input.
-
20011217
Compatibility: Sendmail now has a -L option to set the
Security: subtle hardening of the Postfix chroot jail,
Postfix queue file permissions and access methods, in case
- someone compromises the postfix account. Michael Tokarev
- claims he got the insights from Solar Designer. Files:
+ someone compromises the postfix account. Michael Tokarev,
+ who received the insights from Solar Designer, who tested
+ Postfix with his "openwatch" kernel module. Files:
master/master_wakeup.c, util/fifo_trigger.c, postfix-script.
-Open problems:
+ Convenience: issue a warning instead of aborting when the
+ local machine name is not in fully-qualified domain form.
+ This would otherwise break initial postfix installation
+ which needs the postconf command. File: global/mail_params.c.
+
+20011220
+
+ Added more garbage detection to postconf -e input processing.
+
+20011221
+
+ Feature: SMTPD access map lookups of null sender addresses.
+ If your access maps cannot store or look up null string
+ key values, specify "smtpd_null_access_lookup_key = <>"
+ and the null sender address will be looked up as <> instead.
+ File: src/smtpd_access.c.
+
+20011223
- Low: warn about undomained hostnames instead of aborting.
+ Safety: configuration file comments no longer span multiple
+ lines when the next line begins with whitespace; multi-line
+ input is no longer terminated by a comment line, by an all
+ white space line, or by an empty line. Files: util/readlline.c,
+ postconf/postconf.c.
+
+ Cleanup: proper detection of big number overflow in EHLO
+ and MAIL FROM size announcements. Files: global/off_cvt.c,
+ smtpd/smtpd.c, smtp/smtp_proto.c, util/alldig.c.
+
+ Forward compatibility: added queue file record types for
+ original recipient and for generic named attributes.
+
+ Cleanup: safe_open() now returns sensible errno values so
+ that the fifo_trigger() external interface is restored.
+
+Open problems:
Low: after reorganizing configuration parameters, add flags
to all parameters whose value can be read from file.
- Low: replace null sender address internal representation
- by <> so that it can be looked up reliably in maps. Must
- prevent attempts to rewrite this address with canonical
- maps, or else accidents are bound to happen.
-
Medium: need in-process caching for map lookups. LDAP
servers seem to need this in particular. Need a way to
expire cached results that are too old.
This should be documented, or better, the code should warn
about attempts to set read-only parameters.
- Low: the virtual delivery agent needs a way to specify
- fixed uid/gid for all deliveries.
-
Low: postconf -e edits parameters that postconf won't list.
Postfix queues between Postfix instances anyawy.
For mailbox locking, some systems such as FreeBSD use flock() by
-default. flock() does not work over NFS. This causes loss of mail
-when multiple hosts access the same mailboxes.
+default (use: ``postconf mailbox_delivery_lock'' to find out about
+your system). flock() does not work over NFS. This causes loss of
+mail when multiple hosts access the same mailboxes.
In order to have mailbox locking over NFS you have to configure
everything to use fcntl() locks for mailbox access (or switch to
-Incompatible changes with snapshot-20011217
+Incompatible changes with snapshot-200112XX
===========================================
Postfix configuration file comments no longer continue on the next
line when that next line starts with whitespace. This change avoids
surprises, but it may cause unexpected behavior with existing,
-poorly formatted, configuration files. Caveat user.
+improperly formatted, configuration files. Caveat user.
-Major changes with snapshot-20011217
+Major changes with snapshot-200112XX
====================================
-Postfix configuration files now support whitespace before comments.
-This allows you to comment out just one line in the middle of a
-block of multi-line input. A comment that starts at the beginning
-of a line always terminates previous data.
+In Postfix configuration files, comment lines are allowed to begin
+with whitespace, and multi-line input is no longer terminated by
+a comment line, by an all whitespace line, or by an empty line.
+
+Postfix will now do null address lookups in SMTPD access maps. If
+your access maps cannot store or look up null string key values,
+specify "smtpd_null_access_lookup_key = <>" and the null sender
+address will be looked up as <> instead.
Incompatible changes with snapshot-20011210
===========================================
test -d maildrop || {
$WARN creating missing Postfix maildrop directory
mkdir maildrop || exit 1
- chmod 1733 maildrop
- chown $mail_owner maildrop
+ chmod 1733 maildrop || exit 1
+ chown $mail_owner maildrop || exit 1
}
test -d pid || {
$WARN creating missing Postfix pid directory
mkdir pid || exit 1
- chmod 755 pid
+ chmod 755 pid || exit 1
}
for dir in incoming active bounce defer deferred flush saved corrupt; do
test -d $dir || {
$WARN creating missing Postfix $dir directory
mkdir $dir || exit 1
- chmod 700 $dir; $CHATTR $dir 2>/dev/null
- chown $mail_owner $dir
+ chmod 700 $dir || exit 1
+ $CHATTR $dir 2>/dev/null
+ chown $mail_owner $dir || exit 1
}
done
test -d public || {
$WARN creating missing Postfix public directory
mkdir public || exit 1
- chmod 755 public
- chown $mail_owner public
+ chmod 755 public || exit 1
+ chown $mail_owner public || exit 1
}
test -d private || {
$WARN creating missing Postfix private directory
mkdir private || exit 1
- chmod 700 private
- chown $mail_owner private
+ chmod 700 private || exit 1
+ chown $mail_owner private || exit 1
}
find `ls -d $queue_directory/* | \
egrep '/(incoming|active|defer|deferred|bounce|saved|corrupt|public|private|flush)$'` \
test -d maildrop || {
$WARN creating missing Postfix maildrop directory
mkdir maildrop || exit 1
- chmod 1730 maildrop
- chown $mail_owner maildrop
+ chmod 1730 maildrop || exit 1
+ chown $mail_owner maildrop || exit 1
(. $config_directory/install.cf; chgrp $setgid maildrop)
}
test -d pid || {
$WARN creating missing Postfix pid directory
mkdir pid || exit 1
- chmod 755 pid
+ chmod 755 pid || exit 1
}
for dir in incoming active bounce defer deferred flush saved corrupt; do
test -d $dir || {
$WARN creating missing Postfix $dir directory
mkdir $dir || exit 1
- chmod 700 $dir; $CHATTR $dir 2>/dev/null
- chown $mail_owner $dir
+ chmod 700 $dir || exit 1
+ $CHATTR $dir 2>/dev/null
+ chown $mail_owner $dir || exit 1
}
done
test -d public || {
$WARN creating missing Postfix public directory
mkdir public || exit 1
- chmod 755 public
- chown $mail_owner public
+ chmod 755 public || exit 1
+ chown $mail_owner public || exit 1
}
test -d private || {
$WARN creating missing Postfix private directory
mkdir private || exit 1
- chmod 700 private
- chown $mail_owner private
+ chmod 700 private || exit 1
+ chown $mail_owner private || exit 1
}
find `ls -d $queue_directory/* | \
egrep '/(incoming|active|defer|deferred|bounce|saved|corrupt|public|private|flush)$'` \
When <i>pattern</i> matches a mail address, domain or host
address, perform the corresponding <i>action</i>.
+ blank lines and comments
+ Empty lines and whitespace-only lines are ignored,
+ as are lines whose first non-whitespace character
+ is a `#'.
+
multi-line text
- A line that starts with whitespace (space or tab)
- is a continuation of the previous line. An empty
- line terminates the previous line, as does a line
- that starts with non-whitespace (text or comment).
- A comment line that starts with whitespace does not
- terminate multi-line text.
-
- comments
- The <b>#</b> is recognized as the start of a comment, but
- only when it is the first non-whitespace character
- on a line. A comment terminates at the end of the
- line, even when the next line starts with whites-
- pace.
+ A logical line starts with non-whitespace text. A
+ line that starts with whitespace continues a logi-
+ cal line.
<b>PATTERNS</b>
With lookups from indexed files such as DB or DBM, or from
- networked tables such as NIS, LDAP or SQL, patterns are
+ networked tables such as NIS, LDAP or SQL, patterns are
tried in the order as listed below:
<i>user</i>@<i>domain</i>
Matches the specified mail address.
<i>domain.name</i>
- Matches the <i>domain.name</i> itself and any subdomain
- thereof, either in hostnames or in mail addresses.
+ Matches the <i>domain.name</i> itself and any subdomain
+ thereof, either in hostnames or in mail addresses.
Top-level domains will never be matched.
- <i>user</i>@ Matches all mail addresses with the specified user
+ <i>user</i>@ Matches all mail addresses with the specified user
part.
<i>net.work.addr.ess</i>
<i>net.work</i>
- <i>net</i> Matches any host address in the specified network.
- A network address is a sequence of one or more
+ <i>net</i> Matches any host address in the specified network.
+ A network address is a sequence of one or more
octets separated by ".".
<b>ACTIONS</b>
[<b>45</b>]<i>NN</i> <i>text</i>
- Reject the address etc. that matches the pattern,
+ Reject the address etc. that matches the pattern,
and respond with the numerical code and text.
<b>REJECT</b> Reject the address etc. that matches the pattern. A
<b>reject</b><i>_</i><b>unauth</b><i>_</i><b>destination</b>, and so on).
<b>REGULAR</b> <b>EXPRESSION</b> <b>TABLES</b>
- This section describes how the table lookups change when
+ This section describes how the table lookups change when
the table is given in the form of regular expressions. For
- a description of regular expression lookup table syntax,
+ a description of regular expression lookup table syntax,
see <a href="regexp_table.5.html"><b>regexp</b><i>_</i><b>table</b>(5)</a> or <a href="pcre_table.5.html"><b>pcre</b><i>_</i><b>table</b>(5)</a>.
- Each pattern is a regular expression that is applied to
+ Each pattern is a regular expression that is applied to
the entire string being looked up. Depending on the appli-
- cation, that string is an entire client hostname, an
+ cation, that string is an entire client hostname, an
entire client IP address, or an entire mail address. Thus,
- no parent domain or parent network search is done, and
- <i>user@domain</i> mail addresses are not broken up into their
+ no parent domain or parent network search is done, and
+ <i>user@domain</i> mail addresses are not broken up into their
<i>user@</i> and <i>domain</i> constituent parts.
- Patterns are applied in the order as specified in the
- table, until a pattern is found that matches the search
+ Patterns are applied in the order as specified in the
+ table, until a pattern is found that matches the search
string.
- Actions are the same as with normal indexed file lookups,
- with the additional feature that parenthesized substrings
- from the pattern can be interpolated as <b>$1</b>, <b>$2</b> and so on.
+ Actions are the same as with normal indexed file lookups,
+ with the additional feature that parenthesized substrings
+ from the pattern can be interpolated as <b>$1</b>, <b>$2</b> and so on.
<b>BUGS</b>
- The table format does not understand quoting conventions.
+ The table format does not understand quoting conventions.
<b>SEE</b> <b>ALSO</b>
<a href="postmap.1.html">postmap(1)</a> create mapping table
<a href="regexp_table.5.html">regexp_table(5)</a> format of POSIX regular expression tables
<b>LICENSE</b>
- The Secure Mailer license must be distributed with this
+ The Secure Mailer license must be distributed with this
software.
<b>AUTHOR(S)</b>
<i>name</i>: <i>value1</i>, <i>value2</i>, <i>...</i>
- <b>o</b> A line that starts with whitespace (space or tab)
- is a continuation of the previous line. An empty
- line terminates the previous line, as does a line
- that starts with non-whitespace (text or comment).
- A comment line that starts with whitespace does not
- terminate multi-line text.
-
- <b>o</b> The <b>#</b> is recognized as the start of a comment, but
- only when it is the first non-whitespace character
- on a line. A comment terminates at the end of the
- line, even when the next line starts with whites-
- pace.
-
- The <i>name</i> is a local address (no domain part). Use double
- quotes when the name contains any special characters such
- as whitespace, `#', `:', or `@'. The <i>name</i> is folded to
+ <b>o</b> Empty lines and whitespace-only lines are ignored,
+ as are lines whose first non-whitespace character
+ is a `#'.
+
+ <b>o</b> A logical line starts with non-whitespace text. A
+ line that starts with whitespace continues a logi-
+ cal line.
+
+ The <i>name</i> is a local address (no domain part). Use double
+ quotes when the name contains any special characters such
+ as whitespace, `#', `:', or `@'. The <i>name</i> is folded to
lowercase, in order to make database lookups case insensi-
tive.
In addition, when an alias exists for <b>owner-</b><i>name</i>, delivery
- diagnostics are directed to that address, instead of to
+ diagnostics are directed to that address, instead of to
the originator. This is typically used to direct delivery
- errors to the owner of a mailing list, who is in a better
- position to deal with mailing list delivery problems than
+ errors to the owner of a mailing list, who is in a better
+ position to deal with mailing list delivery problems than
the originator of the undelivered mail.
The <i>value</i> contains one or more of the following:
<i>address</i>
- Mail is forwarded to <i>address</i>, which is compatible
+ Mail is forwarded to <i>address</i>, which is compatible
with the <a href="http://www.faqs.org/rfcs/rfc822.html">RFC 822</a> standard.
<i>/file/name</i>
- Mail is appended to <i>/file/name</i>. See <a href="local.8.html"><b>local</b>(8)</a> for
- details of delivery to file. Delivery is not lim-
- ited to regular files. For example, to dispose of
+ Mail is appended to <i>/file/name</i>. See <a href="local.8.html"><b>local</b>(8)</a> for
+ details of delivery to file. Delivery is not lim-
+ ited to regular files. For example, to dispose of
unwanted mail, deflect it to <b>/dev/null</b>.
|<i>command</i>
- Mail is piped into <i>command</i>. Commands that contain
- special characters, such as whitespace, should be
- enclosed between double quotes. See <a href="local.8.html"><b>local</b>(8)</a> for
+ Mail is piped into <i>command</i>. Commands that contain
+ special characters, such as whitespace, should be
+ enclosed between double quotes. See <a href="local.8.html"><b>local</b>(8)</a> for
details of delivery to command.
When the command fails, a limited amount of command
- output is mailed back to the sender. The file
- <b>/usr/include/sysexits.h</b> defines the expected exit
- status codes. For example, use <b>|"exit</b> <b>67"</b> to simu-
- late a "user unknown" error, and <b>|"exit</b> <b>0"</b> to
+ output is mailed back to the sender. The file
+ <b>/usr/include/sysexits.h</b> defines the expected exit
+ status codes. For example, use <b>|"exit</b> <b>67"</b> to simu-
+ late a "user unknown" error, and <b>|"exit</b> <b>0"</b> to
implement an expensive black hole.
<b>:include:</b><i>/file/name</i>
- Mail is sent to the destinations listed in the
+ Mail is sent to the destinations listed in the
named file. Lines in <b>:include:</b> files have the same
syntax as the right-hand side of alias entries.
<b>ADDRESS</b> <b>EXTENSION</b>
When alias database search fails, and the recipient local-
- part contains the optional recipient delimiter (e.g.,
- <i>user+foo</i>), the search is repeated for the unextended
+ part contains the optional recipient delimiter (e.g.,
+ <i>user+foo</i>), the search is repeated for the unextended
address (e.g., <i>user</i>).
<b>CONFIGURATION</b> <b>PARAMETERS</b>
- The following <b>main.cf</b> parameters are especially relevant
- to this topic. See the Postfix <b>main.cf</b> file for syntax
- details and for default values. Use the <b>postfix</b> <b>reload</b>
+ The following <b>main.cf</b> parameters are especially relevant
+ to this topic. See the Postfix <b>main.cf</b> file for syntax
+ details and for default values. Use the <b>postfix</b> <b>reload</b>
command after a configuration change.
<b>alias</b><i>_</i><b>maps</b>
List of alias databases.
<b>allow</b><i>_</i><b>mail</b><i>_</i><b>to</b><i>_</i><b>commands</b>
- Restrict the usage of mail delivery to external
+ Restrict the usage of mail delivery to external
command.
<b>allow</b><i>_</i><b>mail</b><i>_</i><b>to</b><i>_</i><b>files</b>
- Restrict the usage of mail delivery to external
+ Restrict the usage of mail delivery to external
file.
<b>expand</b><i>_</i><b>owner</b><i>_</i><b>alias</b>
When delivering to an alias that has an <b>owner-</b> com-
- panion alias, set the envelope sender address to
- the right-hand side of the owner alias, instead
+ panion alias, set the envelope sender address to
+ the right-hand side of the owner alias, instead
using of the left-hand side address.
<b>owner</b><i>_</i><b>request</b><i>_</i><b>special</b>
addresses.
<b>recipient</b><i>_</i><b>delimiter</b>
- Delimiter that separates recipients from address
+ Delimiter that separates recipients from address
extensions.
<b>STANDARDS</b>
<a href="postalias.1.html">postalias(1)</a> alias database management
<b>LICENSE</b>
- The Secure Mailer license must be distributed with this
+ The Secure Mailer license must be distributed with this
software.
<b>AUTHOR(S)</b>
When <i>pattern</i> matches a mail address, replace it by
the corresponding <i>result</i>.
+ blank lines and comments
+ Empty lines and whitespace-only lines are ignored,
+ as are lines whose first non-whitespace character
+ is a `#'.
+
multi-line text
- A line that starts with whitespace (space or tab)
- is a continuation of the previous line. An empty
- line terminates the previous line, as does a line
- that starts with non-whitespace (text or comment).
- A comment line that starts with whitespace does not
- terminate multi-line text.
-
- comments
- The <b>#</b> is recognized as the start of a comment, but
- only when it is the first non-whitespace character
- on a line. A comment terminates at the end of the
- line, even when the next line starts with whites-
- pace.
+ A logical line starts with non-whitespace text. A
+ line that starts with whitespace continues a logi-
+ cal line.
With lookups from indexed files such as DB or DBM, or from
- networked tables such as NIS, LDAP or SQL, patterns are
+ networked tables such as NIS, LDAP or SQL, patterns are
tried in the order as listed below:
<i>user</i>@<i>domain</i> <i>address</i>
- <i>user</i>@<i>domain</i> is replaced by <i>address</i>. This form has
+ <i>user</i>@<i>domain</i> is replaced by <i>address</i>. This form has
the highest precedence.
- This form useful to clean up addresses produced by
- legacy mail systems. It can also be used to pro-
- duce <i>Firstname.Lastname</i> style addresses, but see
+ This form useful to clean up addresses produced by
+ legacy mail systems. It can also be used to pro-
+ duce <i>Firstname.Lastname</i> style addresses, but see
below for a simpler solution.
<i>user</i> <i>address</i>
<i>user</i>@<i>site</i> is replaced by <i>address</i> when <i>site</i> is equal
- to $<b>myorigin</b>, when <i>site</i> is listed in $<b>mydestina-</b>
+ to $<b>myorigin</b>, when <i>site</i> is listed in $<b>mydestina-</b>
<b>tion</b>, or when it is listed in $<b>inet</b><i>_</i><b>interfaces</b>.
- This form is useful for replacing login names by
+ This form is useful for replacing login names by
<i>Firstname.Lastname</i>.
@<i>domain</i> <i>address</i>
- Every address in <i>domain</i> is replaced by <i>address</i>.
+ Every address in <i>domain</i> is replaced by <i>address</i>.
This form has the lowest precedence.
- In all the above forms, when <i>address</i> has the form @<i>other-</i>
+ In all the above forms, when <i>address</i> has the form @<i>other-</i>
<i>domain</i>, the result is the same user in <i>otherdomain</i>.
<b>ADDRESS</b> <b>EXTENSION</b>
- When table lookup fails, and the address localpart con-
- tains the optional recipient delimiter (e.g.,
- <i>user+foo</i>@<i>domain</i>), the search is repeated for the unex-
- tended address (e.g. <i>user</i>@<i>domain</i>), and the unmatched
+ When table lookup fails, and the address localpart con-
+ tains the optional recipient delimiter (e.g.,
+ <i>user+foo</i>@<i>domain</i>), the search is repeated for the unex-
+ tended address (e.g. <i>user</i>@<i>domain</i>), and the unmatched
extension is propagated to the result of table lookup. The
matching order is: <i>user+foo</i>@<i>domain</i>, <i>user</i>@<i>domain</i>, <i>user+foo</i>,
<i>user</i>, and @<i>domain</i>.
<b>REGULAR</b> <b>EXPRESSION</b> <b>TABLES</b>
- This section describes how the table lookups change when
+ This section describes how the table lookups change when
the table is given in the form of regular expressions. For
- a description of regular expression lookup table syntax,
+ a description of regular expression lookup table syntax,
see <a href="regexp_table.5.html"><b>regexp</b><i>_</i><b>table</b>(5)</a> or <a href="pcre_table.5.html"><b>pcre</b><i>_</i><b>table</b>(5)</a>.
- Each pattern is a regular expression that is applied to
+ Each pattern is a regular expression that is applied to
the entire address being looked up. Thus, <i>user@domain</i> mail
- addresses are not broken up into their <i>user</i> and <i>@domain</i>
+ addresses are not broken up into their <i>user</i> and <i>@domain</i>
constituent parts, nor is <i>user+foo</i> broken up into <i>user</i> and
<i>foo</i>.
- Patterns are applied in the order as specified in the
- table, until a pattern is found that matches the search
+ Patterns are applied in the order as specified in the
+ table, until a pattern is found that matches the search
string.
- Results are the same as with normal indexed file lookups,
- with the additional feature that parenthesized substrings
- from the pattern can be interpolated as <b>$1</b>, <b>$2</b> and so on.
+ Results are the same as with normal indexed file lookups,
+ with the additional feature that parenthesized substrings
+ from the pattern can be interpolated as <b>$1</b>, <b>$2</b> and so on.
<b>BUGS</b>
- The table format does not understand quoting conventions.
+ The table format does not understand quoting conventions.
<b>CONFIGURATION</b> <b>PARAMETERS</b>
- The following <b>main.cf</b> parameters are especially relevant
- to this topic. See the Postfix <b>main.cf</b> file for syntax
- details and for default values. Use the <b>postfix</b> <b>reload</b>
+ The following <b>main.cf</b> parameters are especially relevant
+ to this topic. See the Postfix <b>main.cf</b> file for syntax
+ details and for default values. Use the <b>postfix</b> <b>reload</b>
command after a configuration change.
<b>canonical</b><i>_</i><b>maps</b>
Other parameters of interest:
<b>inet</b><i>_</i><b>interfaces</b>
- The network interface addresses that this system
+ The network interface addresses that this system
receives mail on.
<b>masquerade</b><i>_</i><b>classes</b>
- List of address classes subject to masquerading:
- zero or more of <b>envelope</b><i>_</i><b>sender</b>, <b>envelope</b><i>_</i><b>recipi-</b>
+ List of address classes subject to masquerading:
+ zero or more of <b>envelope</b><i>_</i><b>sender</b>, <b>envelope</b><i>_</i><b>recipi-</b>
<b>ent</b>, <b>header</b><i>_</i><b>sender</b>, <b>header</b><i>_</i><b>recipient</b>.
<b>masquerade</b><i>_</i><b>domains</b>
- List of domains that hide their subdomain struc-
+ List of domains that hide their subdomain struc-
ture.
<b>masquerade</b><i>_</i><b>exceptions</b>
- List of user names that are not subject to address
+ List of user names that are not subject to address
masquerading.
<b>mydestination</b>
- List of domains that this mail system considers
+ List of domains that this mail system considers
local.
<b>myorigin</b>
<a href="regexp_table.5.html">regexp_table(5)</a> format of POSIX regular expression tables
<b>LICENSE</b>
- The Secure Mailer license must be distributed with this
+ The Secure Mailer license must be distributed with this
software.
<b>AUTHOR(S)</b>
When <i>pattern</i> matches a search string, use the cor-
responding <i>result</i>.
+ blank lines and comments
+ Empty lines and whitespace-only lines are ignored,
+ as are lines whose first non-whitespace character
+ is a `#'.
+
multi-line text
- A line that starts with whitespace (space or tab)
- is a continuation of the previous line. An empty
- line terminates the previous line, as does a line
- that starts with non-whitespace (text or comment).
- A comment line that starts with whitespace does not
- terminate multi-line text.
-
- comments
- The <b>#</b> is recognized as the start of a comment, but
- only when it is the first non-whitespace character
- on a line. A comment terminates at the end of the
- line, even when the next line starts with whites-
- pace.
+ A logical line starts with non-whitespace text. A
+ line that starts with whitespace continues a logi-
+ cal line.
Each pattern is a perl-like regular expression. The
- expression delimiter can be any character, except whites-
- pace or characters that have special meaning (tradition-
- ally the forward slash is used). The regular expression
+ expression delimiter can be any character, except whites-
+ pace or characters that have special meaning (tradition-
+ ally the forward slash is used). The regular expression
can contain whitespace.
By default, matching is case-insensitive, although follow-
- ing the second slash with an `i' flag will reverse this.
- Other flags are supported, but the only other useful one
+ ing the second slash with an `i' flag will reverse this.
+ Other flags are supported, but the only other useful one
is `U', which makes matching ungreedy (see PCRE documenta-
tion and source for more info).
- Each pattern is applied to the entire lookup key string.
- Depending on the application, that string is an entire
+ Each pattern is applied to the entire lookup key string.
+ Depending on the application, that string is an entire
client hostname, an entire client IP address, or an entire
- mail address. Thus, no parent domain or parent network
- search is done, and <i>user@domain</i> mail addresses are not
- broken up into their <i>user</i> and <i>domain</i> constituent parts,
+ mail address. Thus, no parent domain or parent network
+ search is done, and <i>user@domain</i> mail addresses are not
+ broken up into their <i>user</i> and <i>domain</i> constituent parts,
nor is <i>user+foo</i> broken up into <i>user</i> and <i>foo</i>.
- Patterns are applied in the order as specified in the
- table, until a pattern is found that matches the search
+ Patterns are applied in the order as specified in the
+ table, until a pattern is found that matches the search
string.
- Substitution of substrings from the matched expression
- into the result string is possible using the conventional
- perl syntax ($1, $2, etc.). The macros in the result
- string may need to be written as ${n} or $(n) if they
+ Substitution of substrings from the matched expression
+ into the result string is possible using the conventional
+ perl syntax ($1, $2, etc.). The macros in the result
+ string may need to be written as ${n} or $(n) if they
aren't followed by whitespace.
<b>EXAMPLE</b> <b>SMTPD</b> <b>ACCESS</b> <b>MAP</b>
When <i>pattern</i> matches a search string, use the cor-
responding <i>result</i>.
+ blank lines and comments
+ Empty lines and whitespace-only lines are ignored,
+ as are lines whose first non-whitespace character
+ is a `#'.
+
multi-line text
- A line that starts with whitespace (space or tab)
- is a continuation of the previous line. An empty
- line terminates the previous line, as does a line
- that starts with non-whitespace (text or comment).
- A comment line that starts with whitespace does not
- terminate multi-line text.
-
- comments
- The <b>#</b> is recognized as the start of a comment, but
- only when it is the first non-whitespace character
- on a line. A comment terminates at the end of the
- line, even when the next line starts with whites-
- pace.
+ A logical line starts with non-whitespace text. A
+ line that starts with whitespace continues a logi-
+ cal line.
<i>pattern1!pattern2</i> <i>result</i>
Matches <i>pattern1</i> but not <i>pattern2</i>.
Each pattern is a regular expression enclosed by a pair of
delimiters. The regular expression syntax is described in
<i>re_format</i>(7). The expression delimiter can be any charac-
- ter, except whitespace or characters that have special
- meaning (traditionally the forward slash is used). The
+ ter, except whitespace or characters that have special
+ meaning (traditionally the forward slash is used). The
regular expression can contain whitespace.
By default, matching is case-insensitive, although follow-
- ing the second slash with an `i' flag will reverse this.
- Other flags are `x' (disable extended expression syntax),
+ ing the second slash with an `i' flag will reverse this.
+ Other flags are `x' (disable extended expression syntax),
and `m' (enable multi-line mode).
- Each pattern is applied to the entire lookup key string.
- Depending on the application, that string is an entire
+ Each pattern is applied to the entire lookup key string.
+ Depending on the application, that string is an entire
client hostname, an entire client IP address, or an entire
- mail address. Thus, no parent domain or parent network
- search is done, and <i>user@domain</i> mail addresses are not
- broken up into their <i>user</i> and <i>domain</i> constituent parts,
+ mail address. Thus, no parent domain or parent network
+ search is done, and <i>user@domain</i> mail addresses are not
+ broken up into their <i>user</i> and <i>domain</i> constituent parts,
nor is <i>user+foo</i> broken up into <i>user</i> and <i>foo</i>.
- Patterns are applied in the order as specified in the
- table, until a pattern is found that matches the search
+ Patterns are applied in the order as specified in the
+ table, until a pattern is found that matches the search
string.
- Substitution of substrings from the matched expression
+ Substitution of substrings from the matched expression
into the result string is possible using $1, $2, etc.. The
macros in the result string may need to be written as ${n}
or $(n) if they aren't followed by whitespace.
such as an email address, or perhaps a street
address or telephone number.
- <b>o</b> A line that starts with whitespace (space or tab)
- is a continuation of the previous line. An empty
- line terminates the previous line, as does a line
- that starts with non-whitespace (text or comment).
- A comment line that starts with whitespace does not
- terminate multi-line text.
-
- <b>o</b> The <b>#</b> is recognized as the start of a comment, but
- only when it is the first non-whitespace character
- on a line. A comment terminates at the end of the
- line, even when the next line starts with whites-
- pace.
+ <b>o</b> Empty lines and whitespace-only lines are ignored,
+ as are lines whose first non-whitespace character
+ is a `#'.
+
+ <b>o</b> A logical line starts with non-whitespace text. A
+ line that starts with whitespace continues a logi-
+ cal line.
With lookups from indexed files such as DB or DBM, or from
- networked tables such as NIS, LDAP or SQL, the <i>key</i> field
+ networked tables such as NIS, LDAP or SQL, the <i>key</i> field
is one of the following:
<i>user</i>@<i>domain</i>
- Matches <i>user</i>@<i>domain</i>. This form has precedence over
+ Matches <i>user</i>@<i>domain</i>. This form has precedence over
all other forms.
<i>user</i> Matches <i>user</i>@<i>site</i> when <i>site</i> is $<b>myorigin</b>, when <i>site</i>
in $<b>inet</b><i>_</i><b>interfaces</b>.
@<i>domain</i>
- Matches every address in <i>domain</i>. This form has the
+ Matches every address in <i>domain</i>. This form has the
lowest precedence.
<b>ADDRESS</b> <b>EXTENSION</b>
- When the search fails, and the address localpart contains
- the optional recipient delimiter (e.g., <i>user+foo</i>@<i>domain</i>),
- the search is repeated for the unextended address (e.g.
+ When the search fails, and the address localpart contains
+ the optional recipient delimiter (e.g., <i>user+foo</i>@<i>domain</i>),
+ the search is repeated for the unextended address (e.g.
<i>user</i>@<i>domain</i>).
<b>REGULAR</b> <b>EXPRESSION</b> <b>TABLES</b>
- This section describes how the table lookups change when
+ This section describes how the table lookups change when
the table is given in the form of regular expressions. For
- a description of regular expression lookup table syntax,
+ a description of regular expression lookup table syntax,
see <a href="regexp_table.5.html"><b>regexp</b><i>_</i><b>table</b>(5)</a> or <a href="pcre_table.5.html"><b>pcre</b><i>_</i><b>table</b>(5)</a>.
- Each pattern is a regular expression that is applied to
+ Each pattern is a regular expression that is applied to
the entire address being looked up. Thus, <i>user@domain</i> mail
- addresses are not broken up into their <i>user</i> and <i>@domain</i>
+ addresses are not broken up into their <i>user</i> and <i>@domain</i>
constituent parts, nor is <i>user+foo</i> broken up into <i>user</i> and
<i>foo</i>.
- Patterns are applied in the order as specified in the
- table, until a pattern is found that matches the search
+ Patterns are applied in the order as specified in the
+ table, until a pattern is found that matches the search
string.
- Results are the same as with normal indexed file lookups,
- with the additional feature that parenthesized substrings
- from the pattern can be interpolated as <b>$1</b>, <b>$2</b> and so on.
+ Results are the same as with normal indexed file lookups,
+ with the additional feature that parenthesized substrings
+ from the pattern can be interpolated as <b>$1</b>, <b>$2</b> and so on.
<b>BUGS</b>
- The table format does not understand quoting conventions.
+ The table format does not understand quoting conventions.
<b>CONFIGURATION</b> <b>PARAMETERS</b>
- The following <b>main.cf</b> parameters are especially relevant
- to this topic. See the Postfix <b>main.cf</b> file for syntax
- details and for default values. Use the <b>postfix</b> <b>reload</b>
+ The following <b>main.cf</b> parameters are especially relevant
+ to this topic. See the Postfix <b>main.cf</b> file for syntax
+ details and for default values. Use the <b>postfix</b> <b>reload</b>
command after a configuration change.
<b>relocated</b><i>_</i><b>maps</b>
Other parameters of interest:
<b>inet</b><i>_</i><b>interfaces</b>
- The network interface addresses that this system
+ The network interface addresses that this system
receives mail on.
<b>mydestination</b>
- List of domains that this mail system considers
+ List of domains that this mail system considers
local.
<b>myorigin</b>
<a href="regexp_table.5.html">regexp_table(5)</a> format of POSIX regular expression tables
<b>LICENSE</b>
- The Secure Mailer license must be distributed with this
+ The Secure Mailer license must be distributed with this
software.
<b>AUTHOR(S)</b>
<p>
-
By default, Postfix makes no exceptions.
+
<p>
Subtle point: by default, address masquerading is applied only to
the AUTH protocol, and that expect an EHLO response
of "250 AUTH=list" instead of "250 AUTH list".
-<b>Content</b> <b>inspection</b> <b>controls</b>
- <b>content</b><i>_</i><b>filter</b>
- The name of a mail delivery transport that filters
- mail and that either bounces mail or re-injects the
- result back into Postfix. This parameter uses the
- same syntax as the right-hand side of a Postfix
- transport table.
-
<b>smtpd</b><i>_</i><b>noop</b><i>_</i><b>commands</b>
List of commands that are treated as NOOP (no oper-
ation) commands, without any parameter syntax
checking and without any state change. This list
overrides built-in command definitions.
+<b>Content</b> <b>inspection</b> <b>controls</b>
+ <b>content</b><i>_</i><b>filter</b>
+ The name of a mail delivery transport that filters
+ mail and that either bounces mail or re-injects the
+ result back into Postfix. This parameter uses the
+ same syntax as the right-hand side of a Postfix
+ transport table.
+
<b>Authentication</b> <b>controls</b>
<b>enable</b><i>_</i><b>sasl</b><i>_</i><b>authentication</b>
Enable per-session authentication as per <a href="http://www.faqs.org/rfcs/rfc2554.html">RFC 2554</a>
these parameters can then be used instead of the
restriction lists that they represent.
+ <b>smtpd</b><i>_</i><b>null</b><i>_</i><b>access</b><i>_</i><b>lookup</b><i>_</i><b>key</b>
+ The lookup key to be used in SMTPD access tables
+ instead of the null sender address. A null sender
+ address cannot be looked up.
+
<b>maps</b><i>_</i><b>rbl</b><i>_</i><b>domains</b>
List of DNS domains that publish the addresses of
blacklisted hosts.
When <i>pattern</i> matches the domain, use the corre-
sponding <i>result</i>.
+ blank lines and comments
+ Empty lines and whitespace-only lines are ignored,
+ as are lines whose first non-whitespace character
+ is a `#'.
+
multi-line text
- A line that starts with whitespace (space or tab)
- is a continuation of the previous line. An empty
- line terminates the previous line, as does a line
- that starts with non-whitespace (text or comment).
- A comment line that starts with whitespace does not
- terminate multi-line text.
-
- comments
- The <b>#</b> is recognized as the start of a comment, but
- only when it is the first non-whitespace character
- on a line. A comment terminates at the end of the
- line, even when the next line starts with whites-
- pace.
+ A logical line starts with non-whitespace text. A
+ line that starts with whitespace continues a logi-
+ cal line.
With lookups from indexed files such as DB or DBM, or from
- networked tables such as NIS, LDAP or SQL, patterns are
+ networked tables such as NIS, LDAP or SQL, patterns are
tried in the order as listed below:
<i>domain</i> <i>transport</i>:<i>nexthop</i>
- Mail for <i>domain</i> is delivered through <i>transport</i> to
+ Mail for <i>domain</i> is delivered through <i>transport</i> to
<i>nexthop</i>.
<i>.domain</i> <i>transport</i>:<i>nexthop</i>
- Mail for any subdomain of <i>domain</i> is delivered
+ Mail for any subdomain of <i>domain</i> is delivered
through <i>transport</i> to <i>nexthop</i>.
- Note: transport map entries take precedence over domains
- specified in the <b>mydestination</b> parameter. If you use the
+ Note: transport map entries take precedence over domains
+ specified in the <b>mydestination</b> parameter. If you use the
optional transport map, it may be safer to specify
- explicit entries for all domains specified in <b>mydestina-</b>
+ explicit entries for all domains specified in <b>mydestina-</b>
<b>tion</b>, for example:
<b>hostname.my.domain</b> <b>local:</b>
<b>localhost.my.domain</b> <b>local:</b>
- The interpretation of the <i>nexthop</i> field is transport
+ The interpretation of the <i>nexthop</i> field is transport
dependent. In the case of SMTP, specify <i>host</i>:<i>service</i> for a
- non-default server port, and use [<i>host</i>] or [<i>host</i>]:<i>port</i> in
- order to disable MX (mail exchanger) DNS lookups. The []
- form can also be used with IP addresses instead of host-
+ non-default server port, and use [<i>host</i>] or [<i>host</i>]:<i>port</i> in
+ order to disable MX (mail exchanger) DNS lookups. The []
+ form can also be used with IP addresses instead of host-
names.
<b>EXAMPLES</b>
- In order to send mail for <b>foo.org</b> and its subdomains via
+ In order to send mail for <b>foo.org</b> and its subdomains via
the <b>uucp</b> transport to the UUCP host named <b>foo</b>:
<b>foo.org</b> <b>uucp:foo</b>
<b>.foo.org</b> <b>uucp:foo</b>
- When no <i>nexthop</i> host name is specified, the destination
- domain name is used instead. For example, the following
- directs mail for <i>user</i>@<b>foo.org</b> via the <b>slow</b> transport to a
- mail exchanger for <b>foo.org</b>. The <b>slow</b> transport could be
- something that runs at most one delivery process at a
+ When no <i>nexthop</i> host name is specified, the destination
+ domain name is used instead. For example, the following
+ directs mail for <i>user</i>@<b>foo.org</b> via the <b>slow</b> transport to a
+ mail exchanger for <b>foo.org</b>. The <b>slow</b> transport could be
+ something that runs at most one delivery process at a
time:
<b>foo.org</b> <b>slow:</b>
- When no <i>transport</i> is specified, the default transport is
+ When no <i>transport</i> is specified, the default transport is
used, as specified via the <b>default</b><i>_</i><b>transport</b> configuration
- parameter. The following sends all mail for <b>foo.org</b> and
+ parameter. The following sends all mail for <b>foo.org</b> and
its subdomains to host <b>gateway.foo.org</b>:
<b>foo.org</b> <b>:[gateway.foo.org]</b>
<b>.foo.org</b> <b>:[gateway.foo.org]</b>
- In the above example, the [] are used to suppress MX
- lookups. The result would likely point to your local
+ In the above example, the [] are used to suppress MX
+ lookups. The result would likely point to your local
machine.
- In the case of delivery via SMTP, one may specify <i>host-</i>
+ In the case of delivery via SMTP, one may specify <i>host-</i>
<i>name</i>:<i>service</i> instead of just a host:
<b>foo.org</b> <b>smtp:bar.org:2025</b>
- This directs mail for <i>user</i>@<b>foo.org</b> to host <b>bar.org</b> port
- <b>2025</b>. Instead of a numerical port a symbolic name may be
- used. Specify [] around the hostname in order to disable
+ This directs mail for <i>user</i>@<b>foo.org</b> to host <b>bar.org</b> port
+ <b>2025</b>. Instead of a numerical port a symbolic name may be
+ used. Specify [] around the hostname in order to disable
MX lookups.
The error mailer can be used to bounce mail:
- <b>.foo.org</b> <b>error:mail</b> <b>for</b> <b>*.foo.org</b> <b>is</b> <b>not</b> <b>deliv-</b>
+ <b>.foo.org</b> <b>error:mail</b> <b>for</b> <b>*.foo.org</b> <b>is</b> <b>not</b> <b>deliv-</b>
<b>erable</b>
- This causes all mail for <i>user</i>@<i>anything</i><b>.foo.org</b> to be
+ This causes all mail for <i>user</i>@<i>anything</i><b>.foo.org</b> to be
bounced.
<b>REGULAR</b> <b>EXPRESSION</b> <b>TABLES</b>
- This section describes how the table lookups change when
+ This section describes how the table lookups change when
the table is given in the form of regular expressions. For
- a description of regular expression lookup table syntax,
+ a description of regular expression lookup table syntax,
see <a href="regexp_table.5.html"><b>regexp</b><i>_</i><b>table</b>(5)</a> or <a href="pcre_table.5.html"><b>pcre</b><i>_</i><b>table</b>(5)</a>.
- Each pattern is a regular expression that is applied to
+ Each pattern is a regular expression that is applied to
the entire domain being looked up. Thus, <i>some.domain.hier-</i>
<i>archy</i> is not broken up into parent domains.
- Patterns are applied in the order as specified in the
- table, until a pattern is found that matches the search
+ Patterns are applied in the order as specified in the
+ table, until a pattern is found that matches the search
string.
- Results are the same as with normal indexed file lookups,
- with the additional feature that parenthesized substrings
- from the pattern can be interpolated as <b>$1</b>, <b>$2</b> and so on.
+ Results are the same as with normal indexed file lookups,
+ with the additional feature that parenthesized substrings
+ from the pattern can be interpolated as <b>$1</b>, <b>$2</b> and so on.
<b>CONFIGURATION</b> <b>PARAMETERS</b>
- The following <b>main.cf</b> parameters are especially relevant
- to this topic. See the Postfix <b>main.cf</b> file for syntax
- details and for default values. Use the <b>postfix</b> <b>reload</b>
+ The following <b>main.cf</b> parameters are especially relevant
+ to this topic. See the Postfix <b>main.cf</b> file for syntax
+ details and for default values. Use the <b>postfix</b> <b>reload</b>
command after a configuration change.
<b>parent</b><i>_</i><b>domain</b><i>_</i><b>matches</b><i>_</i><b>subdomains</b> (versions >= 20011119)
- List of Postfix features that use <i>domain.name</i> pat-
+ List of Postfix features that use <i>domain.name</i> pat-
terns to match <i>sub.domain.name</i> (as opposed to
requiring <i>.domain.name</i> patterns).
Other parameters of interest:
<b>default</b><i>_</i><b>transport</b>
- The transport to use when no transport is explic-
+ The transport to use when no transport is explic-
itly specified.
<b>relayhost</b>
<a href="regexp_table.5.html">regexp_table(5)</a> format of POSIX regular expression tables
<b>LICENSE</b>
- The Secure Mailer license must be distributed with this
+ The Secure Mailer license must be distributed with this
software.
<b>AUTHOR(S)</b>
When <i>pattern</i> matches a mail address, replace it by
the corresponding <i>result</i>.
+ blank lines and comments
+ Empty lines and whitespace-only lines are ignored,
+ as are lines whose first non-whitespace character
+ is a `#'.
+
multi-line text
- A line that starts with whitespace (space or tab)
- is a continuation of the previous line. An empty
- line terminates the previous line, as does a line
- that starts with non-whitespace (text or comment).
- A comment line that starts with whitespace does not
- terminate multi-line text.
-
- comments
- The <b>#</b> is recognized as the start of a comment, but
- only when it is the first non-whitespace character
- on a line. A comment terminates at the end of the
- line, even when the next line starts with whites-
- pace.
+ A logical line starts with non-whitespace text. A
+ line that starts with whitespace continues a logi-
+ cal line.
With lookups from indexed files such as DB or DBM, or from
- networked tables such as NIS, LDAP or SQL, patterns are
+ networked tables such as NIS, LDAP or SQL, patterns are
tried in the order as listed below:
<i>user</i>@<i>domain</i> <i>address,</i> <i>address,</i> <i>...</i>
- Mail for <i>user</i>@<i>domain</i> is redirected to <i>address</i>.
+ Mail for <i>user</i>@<i>domain</i> is redirected to <i>address</i>.
This form has the highest precedence.
<i>user</i> <i>address,</i> <i>address,</i> <i>...</i>
- Mail for <i>user</i>@<i>site</i> is redirected to <i>address</i> when
- <i>site</i> is equal to $<b>myorigin</b>, when <i>site</i> is listed in
+ Mail for <i>user</i>@<i>site</i> is redirected to <i>address</i> when
+ <i>site</i> is equal to $<b>myorigin</b>, when <i>site</i> is listed in
$mydestination, or when it is listed in
$<i>inet_interfaces</i>.
- This functionality overlaps with functionality of
+ This functionality overlaps with functionality of
the local <i>alias</i>(5) database. The difference is that
- <b>virtual</b> mapping can be applied to non-local
+ <b>virtual</b> mapping can be applied to non-local
addresses.
@<i>domain</i> <i>address,</i> <i>address,</i> <i>...</i>
- Mail for any user in <i>domain</i> is redirected to
+ Mail for any user in <i>domain</i> is redirected to
<i>address</i>. This form has the lowest precedence.
- In all the above forms, when <i>address</i> has the form @<i>other-</i>
- <i>domain</i>, the result is the same user in <i>otherdomain</i>. This
+ In all the above forms, when <i>address</i> has the form @<i>other-</i>
+ <i>domain</i>, the result is the same user in <i>otherdomain</i>. This
works for the first address in the expansion only.
<b>ADDRESS</b> <b>EXTENSION</b>
- When the search fails, and the address localpart contains
- the optional recipient delimiter (e.g., <i>user+foo</i>@<i>domain</i>),
- the search is repeated for the unextended address (e.g.
+ When the search fails, and the address localpart contains
+ the optional recipient delimiter (e.g., <i>user+foo</i>@<i>domain</i>),
+ the search is repeated for the unextended address (e.g.
<i>user</i>@<i>domain</i>), and the unmatched address extension is prop-
- agated to the result of expansion. The matching order is:
+ agated to the result of expansion. The matching order is:
<i>user+foo</i>@<i>domain</i>, <i>user</i>@<i>domain</i>, <i>user+foo</i>, <i>user</i>, and @<i>domain</i>.
<b>REGULAR</b> <b>EXPRESSION</b> <b>TABLES</b>
- This section describes how the table lookups change when
+ This section describes how the table lookups change when
the table is given in the form of regular expressions. For
- a description of regular expression lookup table syntax,
+ a description of regular expression lookup table syntax,
see <a href="regexp_table.5.html"><b>regexp</b><i>_</i><b>table</b>(5)</a> or <a href="pcre_table.5.html"><b>pcre</b><i>_</i><b>table</b>(5)</a>.
- Each pattern is a regular expression that is applied to
+ Each pattern is a regular expression that is applied to
the entire address being looked up. Thus, <i>user@domain</i> mail
- addresses are not broken up into their <i>user</i> and <i>@domain</i>
+ addresses are not broken up into their <i>user</i> and <i>@domain</i>
constituent parts, nor is <i>user+foo</i> broken up into <i>user</i> and
<i>foo</i>.
- Patterns are applied in the order as specified in the
- table, until a pattern is found that matches the search
+ Patterns are applied in the order as specified in the
+ table, until a pattern is found that matches the search
string.
- Results are the same as with normal indexed file lookups,
- with the additional feature that parenthesized substrings
- from the pattern can be interpolated as <b>$1</b>, <b>$2</b> and so on.
+ Results are the same as with normal indexed file lookups,
+ with the additional feature that parenthesized substrings
+ from the pattern can be interpolated as <b>$1</b>, <b>$2</b> and so on.
<b>BUGS</b>
- The table format does not understand quoting conventions.
+ The table format does not understand quoting conventions.
<b>CONFIGURATION</b> <b>PARAMETERS</b>
- The following <b>main.cf</b> parameters are especially relevant
- to this topic. See the Postfix <b>main.cf</b> file for syntax
- details and for default values. Use the <b>postfix</b> <b>reload</b>
+ The following <b>main.cf</b> parameters are especially relevant
+ to this topic. See the Postfix <b>main.cf</b> file for syntax
+ details and for default values. Use the <b>postfix</b> <b>reload</b>
command after a configuration change.
<b>virtual</b><i>_</i><b>maps</b>
Other parameters of interest:
<b>inet</b><i>_</i><b>interfaces</b>
- The network interface addresses that this system
+ The network interface addresses that this system
receives mail on.
<b>mydestination</b>
- List of domains that this mail system considers
+ List of domains that this mail system considers
local.
<b>myorigin</b>
<a href="regexp_table.5.html">regexp_table(5)</a> format of POSIX regular expression tables
<b>LICENSE</b>
- The Secure Mailer license must be distributed with this
+ The Secure Mailer license must be distributed with this
software.
<b>AUTHOR(S)</b>
.IP "\fIpattern action\fR"
When \fIpattern\fR matches a mail address, domain or host address,
perform the corresponding \fIaction\fR.
+.IP "blank lines and comments"
+Empty lines and whitespace-only lines are ignored, as
+are lines whose first non-whitespace character is a `#'.
.IP "multi-line text"
-A line that starts with whitespace (space or tab) is a continuation
-of the previous line. An empty line terminates the previous line,
-as does a line that starts with non-whitespace (text or comment). A
-comment line that starts with whitespace does not terminate multi-line
-text.
-.IP "comments"
-The \fB#\fR is recognized as the start of a comment, but only when it is
-the first non-whitespace character on a line. A comment terminates
-at the end of the line, even when the next line starts with whitespace.
+A logical line starts with non-whitespace text. A line that
+starts with whitespace continues a logical line.
.SH PATTERNS
.na
.nf
.ti +5
\fIname\fR: \fIvalue1\fR, \fIvalue2\fR, \fI...\fR
.IP \(bu
-A line that starts with whitespace (space or tab) is a continuation
-of the previous line. An empty line terminates the previous line,
-as does a line that starts with non-whitespace (text or comment). A
-comment line that starts with whitespace does not terminate multi-line
-text.
+Empty lines and whitespace-only lines are ignored, as
+are lines whose first non-whitespace character is a `#'.
.IP \(bu
-The \fB#\fR is recognized as the start of a comment, but only when it is
-the first non-whitespace character on a line. A comment terminates
-at the end of the line, even when the next line starts with whitespace.
+A logical line starts with non-whitespace text. A line that
+starts with whitespace continues a logical line.
.PP
The \fIname\fR is a local address (no domain part).
Use double quotes when the name contains any special characters
.IP "\fIpattern result\fR"
When \fIpattern\fR matches a mail address, replace it by the
corresponding \fIresult\fR.
+.IP "blank lines and comments"
+Empty lines and whitespace-only lines are ignored, as
+are lines whose first non-whitespace character is a `#'.
.IP "multi-line text"
-A line that starts with whitespace (space or tab) is a continuation
-of the previous line. An empty line terminates the previous line,
-as does a line that starts with non-whitespace (text or comment). A
-comment line that starts with whitespace does not terminate multi-line
-text.
-.IP "comments"
-The \fB#\fR is recognized as the start of a comment, but only when it is
-the first non-whitespace character on a line. A comment terminates
-at the end of the line, even when the next line starts with whitespace.
+A logical line starts with non-whitespace text. A line that
+starts with whitespace continues a logical line.
.PP
With lookups from indexed files such as DB or DBM, or from networked
tables such as NIS, LDAP or SQL, patterns are tried in the order as
.IP "\fIpattern result\fR"
When \fIpattern\fR matches a search string, use the corresponding
\fIresult\fR.
+.IP "blank lines and comments"
+Empty lines and whitespace-only lines are ignored, as
+are lines whose first non-whitespace character is a `#'.
.IP "multi-line text"
-A line that starts with whitespace (space or tab) is a continuation
-of the previous line. An empty line terminates the previous line,
-as does a line that starts with non-whitespace (text or comment). A
-comment line that starts with whitespace does not terminate multi-line
-text.
-.IP "comments"
-The \fB#\fR is recognized as the start of a comment, but only when it is
-the first non-whitespace character on a line. A comment terminates
-at the end of the line, even when the next line starts with whitespace.
+A logical line starts with non-whitespace text. A line that
+starts with whitespace continues a logical line.
.PP
Each pattern is a perl-like regular expression. The expression
delimiter can be any character, except whitespace or characters
.IP "\fIpattern result\fR"
When \fIpattern\fR matches a search string, use the corresponding
\fIresult\fR.
+.IP "blank lines and comments"
+Empty lines and whitespace-only lines are ignored, as
+are lines whose first non-whitespace character is a `#'.
.IP "multi-line text"
-A line that starts with whitespace (space or tab) is a continuation
-of the previous line. An empty line terminates the previous line,
-as does a line that starts with non-whitespace (text or comment). A
-comment line that starts with whitespace does not terminate multi-line
-text.
-.IP "comments"
-The \fB#\fR is recognized as the start of a comment, but only when it is
-the first non-whitespace character on a line. A comment terminates
-at the end of the line, even when the next line starts with whitespace.
+A logical line starts with non-whitespace text. A line that
+starts with whitespace continues a logical line.
.IP "\fIpattern1!pattern2 result\fR"
Matches \fIpattern1\fR but not \fIpattern2\fR.
.PP
Where \fInew_location\fR specifies contact information such as
an email address, or perhaps a street address or telephone number.
.IP \(bu
-A line that starts with whitespace (space or tab) is a continuation
-of the previous line. An empty line terminates the previous line,
-as does a line that starts with non-whitespace (text or comment). A
-comment line that starts with whitespace does not terminate multi-line
-text.
+Empty lines and whitespace-only lines are ignored, as
+are lines whose first non-whitespace character is a `#'.
.IP \(bu
-The \fB#\fR is recognized as the start of a comment, but only when it is
-the first non-whitespace character on a line. A comment terminates
-at the end of the line, even when the next line starts with whitespace.
+A logical line starts with non-whitespace text. A line that
+starts with whitespace continues a logical line.
.PP
With lookups from indexed files such as DB or DBM, or from networked
tables such as NIS, LDAP or SQL, the \fIkey\fR field is one of the
.IP "\fIpattern result\fR"
When \fIpattern\fR matches the domain, use the corresponding
\fIresult\fR.
+.IP "blank lines and comments"
+Empty lines and whitespace-only lines are ignored, as
+are lines whose first non-whitespace character is a `#'.
.IP "multi-line text"
-A line that starts with whitespace (space or tab) is a continuation
-of the previous line. An empty line terminates the previous line,
-as does a line that starts with non-whitespace (text or comment). A
-comment line that starts with whitespace does not terminate multi-line
-text.
-.IP "comments"
-The \fB#\fR is recognized as the start of a comment, but only when it is
-the first non-whitespace character on a line. A comment terminates
-at the end of the line, even when the next line starts with whitespace.
+A logical line starts with non-whitespace text. A line that
+starts with whitespace continues a logical line.
.PP
With lookups from indexed files such as DB or DBM, or from networked
tables such as NIS, LDAP or SQL, patterns are tried in the order as
.IP "\fIpattern result\fR"
When \fIpattern\fR matches a mail address, replace it by the
corresponding \fIresult\fR.
+.IP "blank lines and comments"
+Empty lines and whitespace-only lines are ignored, as
+are lines whose first non-whitespace character is a `#'.
.IP "multi-line text"
-A line that starts with whitespace (space or tab) is a continuation
-of the previous line. An empty line terminates the previous line,
-as does a line that starts with non-whitespace (text or comment). A
-comment line that starts with whitespace does not terminate multi-line
-text.
-.IP "comments"
-The \fB#\fR is recognized as the start of a comment, but only when it is
-the first non-whitespace character on a line. A comment terminates
-at the end of the line, even when the next line starts with whitespace.
+A logical line starts with non-whitespace text. A line that
+starts with whitespace continues a logical line.
.PP
With lookups from indexed files such as DB or DBM, or from networked
tables such as NIS, LDAP or SQL, patterns are tried in the order as
Support older Microsoft clients that mis-implement the AUTH
protocol, and that expect an EHLO response of "250 AUTH=list"
instead of "250 AUTH list".
+.IP \fBsmtpd_noop_commands\fR
+List of commands that are treated as NOOP (no operation) commands,
+without any parameter syntax checking and without any state change.
+This list overrides built-in command definitions.
.SH "Content inspection controls"
.IP \fBcontent_filter\fR
The name of a mail delivery transport that filters mail and that
either bounces mail or re-injects the result back into Postfix.
This parameter uses the same syntax as the right-hand side of
a Postfix transport table.
-.IP \fBsmtpd_noop_commands\fR
-List of commands that are treated as NOOP (no operation) commands,
-without any parameter syntax checking and without any state change.
-This list overrides built-in command definitions.
.SH "Authentication controls"
.IP \fBenable_sasl_authentication\fR
Enable per-session authentication as per RFC 2554 (SASL).
Declares the name of zero or more parameters that contain a
list of UCE restrictions. The names of these parameters can
then be used instead of the restriction lists that they represent.
+.IP \fBsmtpd_null_access_lookup_key\fR
+The lookup key to be used in SMTPD access tables instead of the
+null sender address. A null sender address cannot be looked up.
.IP \fBmaps_rbl_domains\fR
List of DNS domains that publish the addresses of blacklisted
hosts.
# .IP "\fIpattern action\fR"
# When \fIpattern\fR matches a mail address, domain or host address,
# perform the corresponding \fIaction\fR.
+# .IP "blank lines and comments"
+# Empty lines and whitespace-only lines are ignored, as
+# are lines whose first non-whitespace character is a `#'.
# .IP "multi-line text"
-# A line that starts with whitespace (space or tab) is a continuation
-# of the previous line. An empty line terminates the previous line,
-# as does a line that starts with non-whitespace (text or comment). A
-# comment line that starts with whitespace does not terminate multi-line
-# text.
-# .IP "comments"
-# The \fB#\fR is recognized as the start of a comment, but only when it is
-# the first non-whitespace character on a line. A comment terminates
-# at the end of the line, even when the next line starts with whitespace.
+# A logical line starts with non-whitespace text. A line that
+# starts with whitespace continues a logical line.
# PATTERNS
# .ad
# .fi
# .ti +5
# \fIname\fR: \fIvalue1\fR, \fIvalue2\fR, \fI...\fR
# .IP \(bu
-# A line that starts with whitespace (space or tab) is a continuation
-# of the previous line. An empty line terminates the previous line,
-# as does a line that starts with non-whitespace (text or comment). A
-# comment line that starts with whitespace does not terminate multi-line
-# text.
+# Empty lines and whitespace-only lines are ignored, as
+# are lines whose first non-whitespace character is a `#'.
# .IP \(bu
-# The \fB#\fR is recognized as the start of a comment, but only when it is
-# the first non-whitespace character on a line. A comment terminates
-# at the end of the line, even when the next line starts with whitespace.
+# A logical line starts with non-whitespace text. A line that
+# starts with whitespace continues a logical line.
# .PP
# The \fIname\fR is a local address (no domain part).
# Use double quotes when the name contains any special characters
# .IP "\fIpattern result\fR"
# When \fIpattern\fR matches a mail address, replace it by the
# corresponding \fIresult\fR.
+# .IP "blank lines and comments"
+# Empty lines and whitespace-only lines are ignored, as
+# are lines whose first non-whitespace character is a `#'.
# .IP "multi-line text"
-# A line that starts with whitespace (space or tab) is a continuation
-# of the previous line. An empty line terminates the previous line,
-# as does a line that starts with non-whitespace (text or comment). A
-# comment line that starts with whitespace does not terminate multi-line
-# text.
-# .IP "comments"
-# The \fB#\fR is recognized as the start of a comment, but only when it is
-# the first non-whitespace character on a line. A comment terminates
-# at the end of the line, even when the next line starts with whitespace.
+# A logical line starts with non-whitespace text. A line that
+# starts with whitespace continues a logical line.
# .PP
# With lookups from indexed files such as DB or DBM, or from networked
# tables such as NIS, LDAP or SQL, patterns are tried in the order as
# .IP "\fIpattern result\fR"
# When \fIpattern\fR matches a search string, use the corresponding
# \fIresult\fR.
+# .IP "blank lines and comments"
+# Empty lines and whitespace-only lines are ignored, as
+# are lines whose first non-whitespace character is a `#'.
# .IP "multi-line text"
-# A line that starts with whitespace (space or tab) is a continuation
-# of the previous line. An empty line terminates the previous line,
-# as does a line that starts with non-whitespace (text or comment). A
-# comment line that starts with whitespace does not terminate multi-line
-# text.
-# .IP "comments"
-# The \fB#\fR is recognized as the start of a comment, but only when it is
-# the first non-whitespace character on a line. A comment terminates
-# at the end of the line, even when the next line starts with whitespace.
+# A logical line starts with non-whitespace text. A line that
+# starts with whitespace continues a logical line.
# .PP
# Each pattern is a perl-like regular expression. The expression
# delimiter can be any character, except whitespace or characters
# .IP "\fIpattern result\fR"
# When \fIpattern\fR matches a search string, use the corresponding
# \fIresult\fR.
+# .IP "blank lines and comments"
+# Empty lines and whitespace-only lines are ignored, as
+# are lines whose first non-whitespace character is a `#'.
# .IP "multi-line text"
-# A line that starts with whitespace (space or tab) is a continuation
-# of the previous line. An empty line terminates the previous line,
-# as does a line that starts with non-whitespace (text or comment). A
-# comment line that starts with whitespace does not terminate multi-line
-# text.
-# .IP "comments"
-# The \fB#\fR is recognized as the start of a comment, but only when it is
-# the first non-whitespace character on a line. A comment terminates
-# at the end of the line, even when the next line starts with whitespace.
+# A logical line starts with non-whitespace text. A line that
+# starts with whitespace continues a logical line.
# .IP "\fIpattern1!pattern2 result\fR"
# Matches \fIpattern1\fR but not \fIpattern2\fR.
# .PP
# Where \fInew_location\fR specifies contact information such as
# an email address, or perhaps a street address or telephone number.
# .IP \(bu
-# A line that starts with whitespace (space or tab) is a continuation
-# of the previous line. An empty line terminates the previous line,
-# as does a line that starts with non-whitespace (text or comment). A
-# comment line that starts with whitespace does not terminate multi-line
-# text.
+# Empty lines and whitespace-only lines are ignored, as
+# are lines whose first non-whitespace character is a `#'.
# .IP \(bu
-# The \fB#\fR is recognized as the start of a comment, but only when it is
-# the first non-whitespace character on a line. A comment terminates
-# at the end of the line, even when the next line starts with whitespace.
+# A logical line starts with non-whitespace text. A line that
+# starts with whitespace continues a logical line.
# .PP
# With lookups from indexed files such as DB or DBM, or from networked
# tables such as NIS, LDAP or SQL, the \fIkey\fR field is one of the
# .IP "\fIpattern result\fR"
# When \fIpattern\fR matches the domain, use the corresponding
# \fIresult\fR.
+# .IP "blank lines and comments"
+# Empty lines and whitespace-only lines are ignored, as
+# are lines whose first non-whitespace character is a `#'.
# .IP "multi-line text"
-# A line that starts with whitespace (space or tab) is a continuation
-# of the previous line. An empty line terminates the previous line,
-# as does a line that starts with non-whitespace (text or comment). A
-# comment line that starts with whitespace does not terminate multi-line
-# text.
-# .IP "comments"
-# The \fB#\fR is recognized as the start of a comment, but only when it is
-# the first non-whitespace character on a line. A comment terminates
-# at the end of the line, even when the next line starts with whitespace.
+# A logical line starts with non-whitespace text. A line that
+# starts with whitespace continues a logical line.
# .PP
# With lookups from indexed files such as DB or DBM, or from networked
# tables such as NIS, LDAP or SQL, patterns are tried in the order as
# .IP "\fIpattern result\fR"
# When \fIpattern\fR matches a mail address, replace it by the
# corresponding \fIresult\fR.
+# .IP "blank lines and comments"
+# Empty lines and whitespace-only lines are ignored, as
+# are lines whose first non-whitespace character is a `#'.
# .IP "multi-line text"
-# A line that starts with whitespace (space or tab) is a continuation
-# of the previous line. An empty line terminates the previous line,
-# as does a line that starts with non-whitespace (text or comment). A
-# comment line that starts with whitespace does not terminate multi-line
-# text.
-# .IP "comments"
-# The \fB#\fR is recognized as the start of a comment, but only when it is
-# the first non-whitespace character on a line. A comment terminates
-# at the end of the line, even when the next line starts with whitespace.
+# A logical line starts with non-whitespace text. A line that
+# starts with whitespace continues a logical line.
# .PP
# With lookups from indexed files such as DB or DBM, or from networked
# tables such as NIS, LDAP or SQL, patterns are tried in the order as
name = get_hostname();
if ((dot = strchr(name, '.')) == 0) {
if ((domain = mail_conf_lookup_eval(VAR_MYDOMAIN)) == 0)
- msg_fatal("My hostname %s is not a fully qualified name - set %s or %s in %s/main.cf",
- name, VAR_MYHOSTNAME, VAR_MYDOMAIN, var_config_dir);
- name = concatenate(name, ".", domain, (char *) 0);
+ msg_warn("My hostname %s is not a fully qualified name - set %s or %s in %s/main.cf",
+ name, VAR_MYHOSTNAME, VAR_MYDOMAIN, var_config_dir);
+ else
+ name = concatenate(name, ".", domain, (char *) 0);
}
return (name);
}
#define REJECT_UNAUTH_PIPE "reject_unauth_pipelining"
+#define VAR_SMTPD_NULL_KEY "smtpd_null_access_lookup_key"
+#define DEF_SMTPD_NULL_KEY ""
+extern char *var_smtpd_null_key;
+
/*
* Heuristic to reject most unknown recipients at the SMTP port.
*/
* Version of this program.
*/
#define VAR_MAIL_VERSION "mail_version"
-#define DEF_MAIL_VERSION "Snapshot-20011217"
+#define DEF_MAIL_VERSION "Snapshot-20011223"
extern char *var_mail_version;
/* LICENSE
/* Buffer for storage of the result of conversion to string.
/* .IP offset
/* Non-negative off_t value to be converted to string.
-/* BUGS
-/* The string to number conversion routine has no reliable way to
-/* detect an overflow error, so the result may be much smaller
-/* than the number specified in the input.
/* DIAGNOSTICS
/* Panic: negative offset
/* LICENSE
{
int ch;
off_t result;
+ off_t last;
/*
* We're not doing this often, so simplicity has precedence over
- * performance. XXX Need a portable way to correctly detect overflow.
- * Bear in mind that an off_t is not necessarily a long integer, so using
- * raw bit patterns is not going to be a portable solution.
+ * performance.
*/
- for (result = 0; (ch = *(unsigned char *) str) != 0; str++) {
+ for (last = result = 0; (ch = *(unsigned char *) str) != 0; str++) {
if (!ISDIGIT(ch))
return (-1);
result *= 10;
- result += ch - '0';
- if (result < 0)
+ if (result < last)
return (-1);
+ result += ch - '0';
+ last = result;
}
return (result);
}
* Sanity checks
*/
if (offset < 0)
- msg_panic("off_cvt_number: negative offset %s",
+ msg_panic("off_cvt_number: negative offset -%s",
STR(off_cvt_number(buf, -offset)));
/*
REC_TYPE_FROM, "sender",
REC_TYPE_DONE, "done",
REC_TYPE_RCPT, "recipient",
+ REC_TYPE_ORCP, "original recipient",
REC_TYPE_WARN, "warning_message_time",
+ REC_TYPE_ATTR, "named attribute",
REC_TYPE_MESG, "message_content",
REC_TYPE_CONT, "unterminated",
REC_TYPE_NORM, "normal_data",
#define REC_TYPE_FROM 'S' /* sender, required */
#define REC_TYPE_DONE 'D' /* delivered recipient, optional */
#define REC_TYPE_RCPT 'R' /* todo recipient, optional */
+#define REC_TYPE_ORCP 'O' /* original recipient, optional */
#define REC_TYPE_WARN 'W' /* warning message time */
+#define REC_TYPE_ATTR 'A' /* named attribute for extensions */
#define REC_TYPE_MESG 'M' /* start message records */
* record groups. The first member in each set is the record type that
* indicates the end of that record group.
*/
-#define REC_TYPE_ENVELOPE "MCTFILSDRWV"
+#define REC_TYPE_ENVELOPE "MCTFILSDROWVA"
#define REC_TYPE_CONTENT "XLN"
-#define REC_TYPE_EXTRACT "EDRPre"
+#define REC_TYPE_EXTRACT "EDROPre" /* NOT A */
#define REC_TYPE_NOEXTRACT "E"
/*
TOK822 *list;
VSTRING *buf = vstring_alloc(100);
- while (readlline(buf, VSTREAM_IN, (int *) 0, READLL_KEEPNL)) {
+ while (readlline(buf, VSTREAM_IN, (int *) 0)) {
while (VSTRING_LEN(buf) > 0 && vstring_end(buf)[-1] == '\n') {
vstring_end(buf)[-1] = 0;
vstring_truncate(buf, VSTRING_LEN(buf) - 1);
* Skip blank lines and comment lines.
*/
do {
- if (readlline(buf, master_fp, &master_line, READLL_STRIP_NOISE) == 0) {
+ if (readlline(buf, master_fp, &master_line) == 0) {
vstring_free(buf);
vstring_free(junk);
return (0);
* - The postfix user and group ID must not be shared with other
* applications (says the INSTALL documentation).
*
- * Result of a discussion with Michael Tokarev who claims het got
- * his insights from Solar Designer.
+ * Result of a discussion with Michael Tokarev, who received his
+ * insights from Solar Designer, who tested Postfix with his
+ * "openwatch" kernel module.
*/
case MASTER_SERV_TYPE_FIFO:
set_eugid(var_owner_uid, var_owner_gid);
* Add records to the database.
*/
lineno = 0;
- while (readlline(line_buffer, source_fp, &lineno, READLL_STRIP_NOISE)) {
-
- /*
- * Weird stuff. Normally, a line that begins with whitespace is a
- * continuation of the previous line.
- */
- if (ISSPACE(*STR(line_buffer))) {
- msg_warn("%s, line %d: malformed line",
- VSTREAM_PATH(source_fp), lineno);
- continue;
- }
+ while (readlline(line_buffer, source_fp, &lineno)) {
/*
* Tokenize the input, so that we do the right thing when a quoted
#include <mymalloc.h>
#include <argv.h>
#include <split_at.h>
-#include <readlline.h>
+#include <vstring_vstream.h>
#include <myflock.h>
/* Global library. */
VSTRING *buf = vstring_alloc(100);
VSTRING *key = vstring_alloc(10);
char *cp;
- char *value;
+ char *ep;
+ char *edit_key;
+ char *edit_val;
HTABLE *table;
- int first = 1;
struct cvalue {
char *value;
int found;
struct cvalue *cvalue;
HTABLE_INFO **ht_info;
HTABLE_INFO **ht;
+ int interesting;
+
+ /*
+ * Ugly macros to make complex expressions less unreadable.
+ */
+#define SKIP(start, var, cond) \
+ for (var = start; *var && (cond); var++);
+
+#define TRIM(s) { \
+ char *p; \
+ for (p = (s) + strlen(s); p > (s) && ISSPACE(p[-1]); p--); \
+ *p = 0; \
+ }
/*
* Store command-line parameters for quick lookup.
*/
table = htable_create(argc);
while ((cp = *argv++) != 0) {
- if ((value = split_at(cp, '=')) == 0
- || *(cp += strspn(cp, " \t\r\n")) == 0)
- msg_fatal("edit requires \"key = value\" arguments");
- while (*value && ISSPACE(*value))
- value++;
+ if (strchr(cp, '\n') != 0)
+ msg_fatal("edit accepts no multi-line input");
+ SKIP(cp, edit_key, ISSPACE(*edit_key)); /* find key begin */
+ if (*edit_key == '#')
+ msg_fatal("edit accepts no comment input");
+ SKIP(edit_key, ep, !ISSPACE(*ep) && *ep != '='); /* key end */
+ SKIP(ep, cp, ISSPACE(*cp)); /* skip blanks before '=' */
+ if (*cp != '=') /* need '=' */
+ msg_fatal("missing '=' after attribute name: \"%s\"", edit_key);
+ *ep = 0; /* terminate key */
+ cp++; /* skip over '=' */
+ SKIP(cp, edit_val, ISSPACE(*edit_val)); /* skip leading blanks */
+ TRIM(edit_val); /* trim trailing blanks */
cvalue = (struct cvalue *) mymalloc(sizeof(*cvalue));
- cvalue->value = value;
+ cvalue->value = edit_val;
cvalue->found = 0;
- htable_enter(table, mystrtok(&cp, " \t\r\n"), (char *) cvalue);
+ htable_enter(table, edit_key, (char *) cvalue);
}
/*
*/
#define STR(x) vstring_str(x)
- while (readlline(buf, src, (int *) 0, READLL_KEEP_NOISE)) {
- cp = STR(buf);
- if (first) {
- first = 0;
- if (ISSPACE(*cp))
- msg_fatal("%s: file starts with whitespace", path);
- }
- if (*cp == '#') {
+ interesting = 0;
+ while (vstring_get(buf, src) != VSTREAM_EOF) {
+ SKIP(STR(buf), cp, ISSPACE(*cp) /* including newline */ );
+ /* Copy comment, all-whitespace, or empty line. */
+ if (*cp == '#' || *cp == 0) {
vstream_fputs(STR(buf), dst);
- continue;
}
- cp += strspn(cp, " \t\r\n");
- vstring_strncpy(key, cp, strcspn(cp, " \t\r\n="));
- cvalue = (struct cvalue *) htable_find(table, STR(key));
- if (cvalue == 0) {
- vstream_fputs(STR(buf), dst);
- } else {
- if (cvalue->found++ == 1)
- msg_warn("%s: multiple entries for key %s", path, STR(key));
- vstream_fprintf(dst, "%s = %s\n", STR(key), cvalue->value);
+ /* Copy or skip continued text. */
+ else if (cp > STR(buf)) {
+ if (interesting == 0)
+ vstream_fputs(STR(buf), dst);
+ }
+ /* Copy or replace start of logical line. */
+ else {
+ vstring_strncpy(key, cp, strcspn(cp, " \t\r\n="));
+ cvalue = (struct cvalue *) htable_find(table, STR(key));
+ if ((interesting = !!cvalue) != 0) {
+ if (cvalue->found++ == 1)
+ msg_warn("%s: multiple entries for \"%s\"", path, STR(key));
+ vstream_fprintf(dst, "%s = %s\n", STR(key), cvalue->value);
+ } else {
+ vstream_fputs(STR(buf), dst);
+ }
}
}
* Add records to the database.
*/
lineno = 0;
- while (readlline(line_buffer, source_fp, &lineno, READLL_STRIP_NOISE)) {
-
- /*
- * Skip comments.
- */
- if (*STR(line_buffer) == '#')
- continue;
+ while (readlline(line_buffer, source_fp, &lineno)) {
/*
* Split on the first whitespace character, then trim leading and
* trailing whitespace from key and value.
*/
key = STR(line_buffer);
- value = STR(line_buffer) + strcspn(STR(line_buffer), " \t\r\n");
+ value = key + strcspn(key, " \t\r\n");
if (*value)
*value++ = 0;
- while (ISSPACE(*key))
- key++;
while (ISSPACE(*value))
value++;
trimblanks(key, 0)[0] = 0;
trimblanks(value, 0)[0] = 0;
- /*
- * Skip empty lines, or lines with whitespace characters only.
- */
- if (*key == 0 && *value == 0)
- continue;
-
/*
* Enforce the "key whitespace value" format. Disallow missing keys
* or missing values.
VSTRING *sasl_decoded; /* decoding buffer */
sasl_callback_t *sasl_callbacks; /* stateful callbacks */
#endif
+ off_t size_limit; /* server limit or unknown */
} SMTP_STATE;
#define SMTP_FEATURE_ESMTP (1<<0)
state->features |= SMTP_FEATURE_8BITMIME;
else if (strcasecmp(word, "PIPELINING") == 0)
state->features |= SMTP_FEATURE_PIPELINING;
- else if (strcasecmp(word, "SIZE") == 0)
+ else if (strcasecmp(word, "SIZE") == 0) {
state->features |= SMTP_FEATURE_SIZE;
+ if ((word = mystrtok(&words, " \t=")) != 0) {
+ if (!alldig(word))
+ msg_warn("bad size limit \"%s\" in EHLO reply from %s",
+ word, session->namaddr);
+ else
+ state->size_limit = off_cvt_string(word);
+ }
+ }
#ifdef USE_SASL_AUTH
else if (var_smtp_sasl_enable && strcasecmp(word, "AUTH") == 0)
smtp_sasl_helo_auth(state, words);
#define SENDING_MAIL \
(recv_state <= SMTP_STATE_DOT)
+ /*
+ * See if we should even try to send this message at all. This code sits
+ * here rather than in the EHLO processing code, because of future SMTP
+ * connection caching.
+ */
+ if (state->size_limit > 0 && state->size_limit < request->data_size) {
+ smtp_mesg_fail(state, resp->code,
+ "message size %lu exceeds size limit %.0f of server %s",
+ request->data_size, (double) state->size_limit,
+ session->namaddr);
+ return (0);
+ }
+
/*
* We use SMTP command pipelining if the server said it supported it.
* Since we use blocking I/O, RFC 2197 says that we should inspect the
#ifdef USE_SASL_AUTH
smtp_sasl_connect(state);
#endif
+ state->size_limit = 0;
return (state);
}
/* Support older Microsoft clients that mis-implement the AUTH
/* protocol, and that expect an EHLO response of "250 AUTH=list"
/* instead of "250 AUTH list".
+/* .IP \fBsmtpd_noop_commands\fR
+/* List of commands that are treated as NOOP (no operation) commands,
+/* without any parameter syntax checking and without any state change.
+/* This list overrides built-in command definitions.
/* .SH "Content inspection controls"
/* .IP \fBcontent_filter\fR
/* The name of a mail delivery transport that filters mail and that
/* either bounces mail or re-injects the result back into Postfix.
/* This parameter uses the same syntax as the right-hand side of
/* a Postfix transport table.
-/* .IP \fBsmtpd_noop_commands\fR
-/* List of commands that are treated as NOOP (no operation) commands,
-/* without any parameter syntax checking and without any state change.
-/* This list overrides built-in command definitions.
/* .SH "Authentication controls"
/* .IP \fBenable_sasl_authentication\fR
/* Enable per-session authentication as per RFC 2554 (SASL).
/* Declares the name of zero or more parameters that contain a
/* list of UCE restrictions. The names of these parameters can
/* then be used instead of the restriction lists that they represent.
+/* .IP \fBsmtpd_null_access_lookup_key\fR
+/* The lookup key to be used in SMTPD access tables instead of the
+/* null sender address. A null sender address cannot be looked up.
/* .IP \fBmaps_rbl_domains\fR
/* List of DNS domains that publish the addresses of blacklisted
/* hosts.
char *var_perm_mx_networks;
char *var_smtpd_snd_auth_maps;
char *var_smtpd_noop_cmds;
+char *var_smtpd_null_key;
/*
* Global state, for stand-alone mode queue file cleanup. When this is
state->msg_size = 0;
/*
- * Sanity checks. XXX Ignore bad SIZE= values until we can reliably and
- * portably detect overflows while converting from string to off_t.
+ * Sanity checks.
*
* XXX 2821 pedantism: Section 4.1.2 says that SMTP servers that receive a
* command in which invalid character codes have been employed, and for
|| strcasecmp(arg, "BODY=7BIT") == 0) {
/* void */ ;
} else if (strncasecmp(arg, "SIZE=", 5) == 0) {
- if ((state->msg_size = off_cvt_string(arg + 5)) < 0)
- state->msg_size = 0;
+ /* Reject non-numeric size. */
+ if (!alldig(arg + 5)) {
+ state->error_mask |= MAIL_ERROR_PROTOCOL;
+ smtpd_chat_reply(state, "501 Bad message size syntax");
+ return (-1);
+ }
+ /* Reject size overflow. */
+ if ((state->msg_size = off_cvt_string(arg + 5)) < 0) {
+ smtpd_chat_reply(state, "552 Message size exceeds file system imposed limit");
+ state->error_mask |= MAIL_ERROR_POLICY;
+ return (-1);
+ }
#ifdef USE_SASL_AUTH
} else if (var_smtpd_sasl_enable && strncasecmp(arg, "AUTH=", 5) == 0) {
if ((err = smtpd_sasl_mail_opt(state, arg + 5)) != 0) {
VAR_PERM_MX_NETWORKS, DEF_PERM_MX_NETWORKS, &var_perm_mx_networks, 0, 0,
VAR_SMTPD_SND_AUTH_MAPS, DEF_SMTPD_SND_AUTH_MAPS, &var_smtpd_snd_auth_maps, 0, 0,
VAR_SMTPD_NOOP_CMDS, DEF_SMTPD_NOOP_CMDS, &var_smtpd_noop_cmds, 0, 0,
+ VAR_SMTPD_NULL_KEY, DEF_SMTPD_NULL_KEY, &var_smtpd_null_key, 0, 0,
0,
};
* All-numeric result probably means OK - some out-of-band authentication
* mechanism uses this as time stamp.
*/
- if (*value && value[strspn(value, "0123456789")] == 0)
+ if (alldig(value))
return (SMTPD_CHECK_OK);
/*
if (login) {
if (owner == 0 || strcasecmp(login, owner) != 0)
return (smtpd_check_reject(state, MAIL_ERROR_POLICY,
- "553 <%s>: Sender address rejected: not owned by username %s",
+ "553 <%s>: Sender address rejected: not owned by user %s",
sender, login));
} else {
if (owner)
status = check_mail_access(state, *cpp, state->sender,
&found, state->sender,
SMTPD_NAME_SENDER, def_acl);
+ if (state->sender && !*state->sender)
+ status = check_access(state, *cpp, var_smtpd_null_key, FULL,
+ &found, state->sender,
+ SMTPD_NAME_SENDER, def_acl);
} else if (strcasecmp(name, REJECT_UNKNOWN_ADDRESS) == 0) {
if (state->sender && *state->sender)
status = reject_unknown_address(state, state->sender,
char *var_local_rcpt_maps;
char *var_perm_mx_networks;
char *var_par_dom_match;
+char *var_smtpd_null_key;
+char *var_smtpd_snd_auth_maps;
typedef struct {
char *name;
VAR_LOCAL_RCPT_MAPS, DEF_LOCAL_RCPT_MAPS, &var_local_rcpt_maps,
VAR_PERM_MX_NETWORKS, DEF_PERM_MX_NETWORKS, &var_perm_mx_networks,
VAR_PAR_DOM_MATCH, DEF_PAR_DOM_MATCH, &var_par_dom_match,
+ VAR_SMTPD_SND_AUTH_MAPS, DEF_SMTPD_SND_AUTH_MAPS, &var_smtpd_snd_auth_maps,
+ VAR_SMTPD_NULL_KEY, DEF_SMTPD_NULL_KEY, &var_smtpd_null_key,
0,
};
typedef struct {
char *name;
ARGV **target;
-} REST_TABLE;
+} REST_TABLE;
static REST_TABLE rest_table[] = {
"client_restrictions", &client_restrctions,
{
if (addr == STR(result))
msg_panic("canon_addr_internal: result clobbers input");
- if (strchr(addr, '@') == 0)
+ if (*addr && strchr(addr, '@') == 0)
msg_fatal("%s: address rewriting is disabled", addr);
vstring_strcpy(result, addr);
}
ARGV *args;
char *bp;
char *resp;
+ char *addr;
/*
* Initialization. Use dummies for client information.
/*
* Try restrictions.
*/
+#define TRIM_ADDR(src, res) { \
+ if (*(res = src) == '<') { \
+ res += strlen(res) - 1; \
+ if (*res == '>') \
+ *res = 0; \
+ res = src + 1; \
+ } \
+ }
+
if (strcasecmp(args->argv[0], "helo") == 0) {
state.where = "HELO";
resp = smtpd_check_helo(&state, args->argv[1]);
UPDATE_STRING(state.helo_name, args->argv[1]);
} else if (strcasecmp(args->argv[0], "mail") == 0) {
state.where = "MAIL";
- resp = smtpd_check_mail(&state, args->argv[1]);
- UPDATE_STRING(state.sender, args->argv[1]);
+ TRIM_ADDR(args->argv[1], addr);
+ UPDATE_STRING(state.sender, addr);
+ resp = smtpd_check_mail(&state, addr);
} else if (strcasecmp(args->argv[0], "rcpt") == 0) {
state.where = "RCPT";
- (resp = smtpd_check_rcpt(&state, args->argv[1]))
- || (resp = smtpd_check_rcptmap(&state, args->argv[1]));
+ TRIM_ADDR(args->argv[1], addr);
+ (resp = smtpd_check_rcpt(&state, addr))
+ || (resp = smtpd_check_rcptmap(&state, addr));
}
break;
SHELL = /bin/sh
-SRCS = argv.c argv_split.c attr_print0.c attr_print64.c attr_scan0.c \
- attr_scan64.c base64_code.c basename.c binhash.c chroot_uid.c \
- clean_env.c close_on_exec.c concatenate.c ctable.c dict.c \
- dict_alloc.c dict_db.c dict_dbm.c dict_debug.c dict_env.c \
+SRCS = alldig.c argv.c argv_split.c attr_print0.c attr_print64.c \
+ attr_scan0.c attr_scan64.c base64_code.c basename.c binhash.c \
+ chroot_uid.c clean_env.c close_on_exec.c concatenate.c ctable.c \
+ dict.c dict_alloc.c dict_db.c dict_dbm.c dict_debug.c dict_env.c \
dict_ht.c dict_ldap.c dict_mysql.c dict_ni.c dict_nis.c \
dict_nisplus.c dict_open.c dict_pcre.c dict_regexp.c dict_static.c \
dict_tcp.c dict_unix.c dir_forest.c doze.c duplex_pipe.c \
valid_hostname.c vbuf.c vbuf_print.c vstream.c vstream_popen.c \
vstring.c vstring_vstream.c watchdog.c writable.c write_buf.c \
write_wait.c
-OBJS = argv.o argv_split.o attr_print0.o attr_print64.o attr_scan0.o \
- attr_scan64.o base64_code.o basename.o binhash.o chroot_uid.o \
- clean_env.o close_on_exec.o concatenate.o ctable.o dict.o \
- dict_alloc.o dict_db.o dict_dbm.o dict_debug.o dict_env.o \
+OBJS = alldig.o argv.o argv_split.o attr_print0.o attr_print64.o \
+ attr_scan0.o attr_scan64.o base64_code.o basename.o binhash.o \
+ chroot_uid.o clean_env.o close_on_exec.o concatenate.o ctable.o \
+ dict.o dict_alloc.o dict_db.o dict_dbm.o dict_debug.o dict_env.o \
dict_ht.o dict_ldap.o dict_mysql.o dict_ni.o dict_nis.o \
dict_nisplus.o dict_open.o dict_pcre.o dict_regexp.o dict_static.o \
dict_tcp.o dict_unix.o dir_forest.o doze.o duplex_pipe.o \
../postmap/postmap -n testdb
./dict_open $(DB_TYPE):testdb write < dict_test.in > dict_test.tmp 2>&1
diff dict_test.ref dict_test.tmp
- rm -f testdb.db testdb.dir testdb.pag
+ rm -f testdb.db testdb.dir testdb.pag dict_test.tmp
# do not edit below this line - it is generated by 'make depend'
+alldig.o: alldig.c
+alldig.o: sys_defs.h
+alldig.o: stringops.h
+alldig.o: vstring.h
+alldig.o: vbuf.h
argv.o: argv.c
argv.o: sys_defs.h
argv.o: mymalloc.h
readable.o: iostuff.h
readlline.o: readlline.c
readlline.o: sys_defs.h
+readlline.o: msg.h
readlline.o: vstream.h
readlline.o: vbuf.h
readlline.o: vstring.h
--- /dev/null
+/*++
+/* NAME
+/* alldig 3
+/* SUMMARY
+/* predicate if string is all numerical
+/* SYNOPSIS
+/* #include <stringops.h>
+/*
+/* int alldig(string)
+/* const char *string;
+/* DESCRIPTION
+/* alldig() determines if its argument is an all-numerical string.
+/* SEE ALSO
+/* An alldig() routine appears in Brian W. Kernighan, P.J. Plauger:
+/* "Software Tools", Addison-Wesley 1976.
+/* LICENSE
+/* .ad
+/* .fi
+/* The Secure Mailer license must be distributed with this software.
+/* AUTHOR(S)
+/* Wietse Venema
+/* IBM T.J. Watson Research
+/* P.O. Box 704
+/* Yorktown Heights, NY 10598, USA
+/*--*/
+
+/* System library. */
+
+#include <sys_defs.h>
+#include <ctype.h>
+
+/* Utility library. */
+
+#include <stringops.h>
+
+/* alldig - return true if string is all digits */
+
+int alldig(const char *string)
+{
+ const char *cp;
+
+ if (*string == 0)
+ return (0);
+ for (cp = string; *cp != 0; cp++)
+ if (!ISDIGIT(*cp))
+ return (0);
+ return (1);
+}
buf = vstring_alloc(100);
lineno = 0;
- while (readlline(buf, fp, &lineno, READLL_STRIP_NOISE)) {
+ while (readlline(buf, fp, &lineno)) {
start = STR(buf);
SKIP(start, member, ISSPACE(*member)); /* find member begin */
SKIP(member, ep, !ISSPACE(*ep) && *ep != '='); /* find member end */
SKIP(ep, cp, ISSPACE(*cp)); /* skip blanks before '=' */
- if (*cp && *cp != '=') /* need '=' or end of string */
- msg_fatal("%s, line %d: whitespace in attribute name: \"%s\"",
+ if (*cp != '=') /* need '=' */
+ msg_fatal("%s, line %d: missing '=' after attribute name: \"%s\"",
VSTREAM_PATH(fp), lineno, member);
- if (*cp)
- cp++; /* skip over '=' */
*ep = 0; /* terminate member name */
+ cp++; /* skip over '=' */
SKIP(cp, val, ISSPACE(*val)); /* skip leading blanks */
TRIM(val); /* trim trailing blanks */
dict_update(dict_name, member, val);
int main(int argc, char **argv)
{
VSTRING *keybuf = vstring_alloc(1);
+ VSTRING *inbuf = vstring_alloc(1);
DICT *dict;
char *dict_name;
int open_flags;
dict_name = argv[optind];
dict = dict_open(dict_name, open_flags, DICT_FLAG_LOCK);
dict_register(dict_name, dict);
- while (vstring_fgets_nonl(keybuf, VSTREAM_IN)) {
- bufp = vstring_str(keybuf);
- if ((cmd = mystrtok(&bufp, " ")) == 0)
+ while (vstring_fgets_nonl(inbuf, VSTREAM_IN)) {
+ bufp = vstring_str(inbuf);
+ if ((cmd = mystrtok(&bufp, " ")) == 0 || *bufp == 0) {
+ vstream_printf("usage: del key|get key|put key=value\n");
+ vstream_fflush(VSTREAM_OUT);
continue;
+ }
if (dict_changed())
msg_warn("dictionary has changed");
- key = mystrtok(&bufp, " =");
+ key = vstring_str(unescape(keybuf, mystrtok(&bufp, " =")));
value = mystrtok(&bufp, " =");
if (strcmp(cmd, "del") == 0 && key && !value) {
if (dict_del(dict, key))
vstream_fflush(VSTREAM_OUT);
}
vstring_free(keybuf);
+ vstring_free(inbuf);
dict_close(dict);
return (0);
}
if ((map_fp = vstream_fopen(map, O_RDONLY, 0)) == 0) {
msg_fatal("open %s: %m", map);
}
- while (readlline(line_buffer, map_fp, &lineno, READLL_STRIP_NOISE)) {
+ while (readlline(line_buffer, map_fp, &lineno)) {
p = vstring_str(line_buffer);
trimblanks(p, 0)[0] = 0; /* Trim space at end */
if ((map_fp = vstream_fopen(map, O_RDONLY, 0)) == 0) {
msg_fatal("open %s: %m", map);
}
- while (readlline(line_buffer, map_fp, &lineno, READLL_STRIP_NOISE)) {
+ while (readlline(line_buffer, map_fp, &lineno)) {
p = vstring_str(line_buffer);
trimblanks(p, 0)[0] = 0; /* Trim space at end */
/* int timeout;
/* DESCRIPTION
/* fifo_trigger() wakes up the named fifo server by writing
-/* the contents of the specified buffer to the fifo.
+/* the contents of the specified buffer to the fifo. There is
+/* no guarantee that the written data will actually be received.
/*
/* Arguments:
/* .IP service
/* Deadline in seconds. Specify a value <= 0 to disable
/* the time limit.
/* DIAGNOSTICS
-/* The result is zero in case of success, -1 in case of problems.
+/* The result is zero when the fifo could be opened, -1 otherwise.
/* BUGS
/* LICENSE
/* .ad
int fifo_trigger(const char *service, const char *buf, int len, int timeout)
{
+ static VSTRING *why;
char *myname = "fifo_trigger";
VSTREAM *fp;
int fd;
+ if (why == 0)
+ why = vstring_alloc(1);
+
/*
* Write the request to the service fifo. According to POSIX, the open
* shall always return immediately, and shall return an error when no
* process is reading from the FIFO.
*
- * Use safe_open() so that we don't follow arbitrary symlinks.
+ * Use safe_open() so that we don't follow symlinks, and so that we don't
+ * open files with multiple hard links. We're not (yet) going to bother
+ * the caller with safe_open() specific quirks such as the why argument.
*/
if ((fp = safe_open(service, O_WRONLY | O_NONBLOCK, 0,
- (struct stat *) 0, -1, -1, (VSTRING *) 0)) == 0) {
+ (struct stat *) 0, -1, -1, why)) == 0) {
if (msg_verbose)
- msg_info("%s: open %s: %m", myname, service);
+ msg_info("%s: open %s: %s", myname, service, vstring_str(why));
return (-1);
}
fd = vstream_fileno(fp);
/* SYNOPSIS
/* #include <readlline.h>
/*
-/* VSTRING *readlline(buf, fp, lineno, strip_noise)
+/* VSTRING *readlline(buf, fp, lineno)
/* VSTRING *buf;
/* VSTREAM *fp;
/* int *lineno;
-/* int strip_noise;
/* DESCRIPTION
/* readlline() reads one logical line from the named stream.
-/*
-/* A line that starts with whitespace (space or tab) is a continuation
-/* of the previous line. An empty line terminates the previous line,
-/* as does a line that starts with non-whitespace (text or comment). A
-/* comment line that starts with whitespace does not terminate multi-line
-/* text.
-/*
-/* The # is recognized as the start of a comment, but only when it is
-/* the first non-whitespace character on a line. A comment terminates
-/* at the end of the line, even when the next line starts with whitespace.
-/*
+/* .IP "blank lines and comments"
+/* Empty lines and whitespace-only lines are ignored, as
+/* are lines whose first non-whitespace character is a `#'.
+/* .IP "multi-line text"
+/* A logical line starts with non-whitespace text. A line that
+/* starts with whitespace continues a logical line.
+/* .PP
/* The result value is the input buffer argument or a null pointer
/* when no input is found.
/*
/* Arguments:
/* .IP buf
-/* A variable-length buffer for input.
+/* A variable-length buffer for input. The result is null terminated.
/* .IP fp
/* Handle to an open stream.
/* .IP lineno
/* A null pointer, or a pointer to an integer that is incremented
-/* after reading a newline.
-/* .IP strip_noise
-/* Non-zero to strip newlines, empty lines and comments from the result.
-/* For convenience, READLL_STRIP_NOISE requests stripping while
-/* READLL_KEEP_NOISE disables stripping.
+/* after reading a newline character.
/* .RE
+/* DIAGNOSTICS
+/* Warning: a continuation line that does not continue preceding text.
+/* The invalid input is ignored, to avoid complicating caller code.
/* LICENSE
/* .ad
/* .fi
/* System library. */
#include <sys_defs.h>
+#include <ctype.h>
/* Utility library. */
+#include "msg.h"
#include "vstream.h"
#include "vstring.h"
#include "readlline.h"
- /*
- * Comment stripper states. States are (1)->(2) or (1)->(3) as we proceed
- * through a line of text.
- */
-#define READLL_STATE_WANT_LWSP 1 /* expecting leading whitespace */
-#define READLL_STATE_IN_COMMENT 2 /* inside comment */
-#define READLL_STATE_IN_TEXT 3 /* inside other text */
-
-#define LWSP_CHARACTER(ch) ((ch) == ' ' || (ch) == '\t')
-
#define STR(x) vstring_str(x)
+#define LEN(x) VSTRING_LEN(x)
+#define END(x) vstring_end(x)
/* readlline - read one logical line */
-VSTRING *readlline(VSTRING *buf, VSTREAM *fp, int *lineno, int strip_noise)
+VSTRING *readlline(VSTRING *buf, VSTREAM *fp, int *lineno)
{
int ch;
int next;
- int state;
+ int start;
+ char *cp;
- /*
- * Lines that start with whitespace continue the preceding line. Comments
- * always terminate at the first newline.
- */
VSTRING_RESET(buf);
- if (strip_noise)
- state = READLL_STATE_WANT_LWSP;
- while ((ch = VSTREAM_GETC(fp)) != VSTREAM_EOF) {
- /* Skip leading whitespace that doesn't continue a previous line. */
- if (VSTRING_LEN(buf) == 0 && LWSP_CHARACTER(ch))
- continue;
- if (ch == '\n') {
- if (lineno)
- *lineno += 1;
- if (strip_noise) {
- state = READLL_STATE_WANT_LWSP;
- /* Skip empty, whitespace, or comment line before text. */
- if (VSTRING_LEN(buf) == 0)
- continue;
- } else {
- VSTRING_ADDCH(buf, ch);
- /* Terminate empty, whitespace, or comment line before text. */
- if (VSTRING_LEN(buf) == 1 || STR(buf)[0] == '#')
- break;
- }
- next = VSTREAM_GETC(fp);
- /* Continue this line if the next line starts with whitespace. */
- if (LWSP_CHARACTER(next)) {
- ch = next;
- } else {
- if (next != VSTREAM_EOF)
- vstream_ungetc(fp, next);
+ /*
+ * Ignore comment lines, all whitespace lines, and empty lines. Terminate
+ * at EOF or at the beginning of the next logical line.
+ */
+ for (;;) {
+ /* Read one line, possibly not newline terminated. */
+ start = LEN(buf);
+ while ((ch = VSTREAM_GETC(fp)) != VSTREAM_EOF && ch != '\n')
+ VSTRING_ADDCH(buf, ch);
+ if (ch == '\n' && lineno != 0)
+ *lineno += 1;
+ /* Ignore comment line, all whitespace line, or empty line. */
+ for (cp = STR(buf) + start; cp < END(buf) && ISSPACE(*cp); cp++)
+ /* void */ ;
+ if (cp == END(buf) || *cp == '#')
+ vstring_truncate(buf, start);
+ /* Terminate at EOF or at the beginning of the next logical line. */
+ if (ch == VSTREAM_EOF)
+ break;
+ if (LEN(buf) > 0) {
+ if ((next = VSTREAM_GETC(fp)) != VSTREAM_EOF)
+ vstream_ungetc(fp, next);
+ if (next != '#' && !ISSPACE(next))
break;
- }
}
- /* Update the comment stripping state machine. */
- if (strip_noise) {
- if (state == READLL_STATE_WANT_LWSP) {
- if (ch == '#') {
- state = READLL_STATE_IN_COMMENT;
- } else if (!LWSP_CHARACTER(ch)) {
- state = READLL_STATE_IN_TEXT;
- }
- }
- if (state == READLL_STATE_IN_COMMENT)
- continue;
- }
- VSTRING_ADDCH(buf, ch);
}
+
+ /*
+ * Invalid input: continuing text without preceding text. Allowing this
+ * would complicate "postconf -e", which implements its own multi-line
+ * parsing routine. Do not abort, just warn, so that critical programs
+ * like postmap do not leave behind a truncated table.
+ */
+ if (LEN(buf) > 0 && ISSPACE(*STR(buf))) {
+ msg_warn("%s: logical line must not start with whitespace: \"%.30s%s\"",
+ VSTREAM_PATH(fp), STR(buf),
+ LEN(buf) > 100 ? "..." : "");
+ return (readlline(buf, fp, lineno));
+ }
+
+ /*
+ * Done.
+ */
VSTRING_TERMINATE(buf);
- return (VSTRING_LEN(buf) || ch == '\n' ? buf : 0);
+ return (LEN(buf) > 0 ? buf : 0);
}
/*
* External interface.
*/
-extern VSTRING *readlline(VSTRING *, VSTREAM *, int *, int);
-
-#define READLL_STRIP_NOISE 1
-#define READLL_KEEP_NOISE 0
+extern VSTRING *readlline(VSTRING *, VSTREAM *, int *);
/* LICENSE
/* .ad
/* Panic: interface violations.
/*
/* A null result means there was a problem. The nature of the
-/* problem is returned via the \fIwhy\fR buffer; some errors
-/* cannot be reported via \fIerrno\fR.
+/* problem is returned via the \fIwhy\fR buffer; when an error
+/* cannot be reported via \fIerrno\fR, the generic value EPERM
+/* (operation not permitted) is used instead.
/* HISTORY
/* .fi
/* .ad
/* be fooled by delaying the open() until the inode found with
/* lstat() has been re-used for a sensitive file (article
/* <20000103212443.A5807@monad.swb.de> posted to bugtraq on
-/* Jan 3, 2000). This can be a concern for a set-uid process
+/* Jan 3, 2000). This can be a concern for a set-ugid process
/* that runs under the control of a user and that can be
/* manipulated with start/stop signals.
/* LICENSE
} else if (fstat_st->st_nlink != 1) {
vstring_sprintf(why, "file has %d hard links",
(int) fstat_st->st_nlink);
+ errno = EPERM;
} else if (S_ISDIR(fstat_st->st_mode)) {
vstring_sprintf(why, "file is a directory");
+ errno = EISDIR;
}
/*
*/
else if (lstat(path, &lstat_st) < 0) {
vstring_sprintf(why, "file status changed unexpectedly: %m");
+ errno = EPERM;
} else if (S_ISLNK(lstat_st.st_mode)) {
if (lstat_st.st_uid == 0)
return (fp);
vstring_sprintf(why, "file is a symbolic link");
+ errno = EPERM;
} else if (fstat_st->st_dev != lstat_st.st_dev
|| fstat_st->st_ino != lstat_st.st_ino
#ifdef HAS_ST_GEN
|| fstat_st->st_nlink != lstat_st.st_nlink
|| fstat_st->st_mode != lstat_st.st_mode) {
vstring_sprintf(why, "file status changed unexpectedly");
+ errno = EPERM;
}
/*
/*
* End up here in case of fstat()/lstat() problems or inconsistencies.
- * Reset errno to reduce confusion.
*/
- errno = 0;
vstream_fclose(fp);
return (0);
}
if (CHANGE_OWNER(user, group)
&& fchown(vstream_fileno(fp), user, group) < 0) {
- vstring_sprintf(why, "cannot change file ownership: %m");
+ msg_warn("%s: cannot change file ownership: %m", path);
}
/*
extern char *basename(const char *);
#endif
extern VSTRING *unescape(VSTRING *, const char *);
+extern int alldig(const char *);
/* LICENSE
/* .ad