mirror of
https://github.com/vdukhovni/postfix
synced 2025-08-30 13:48:06 +00:00
postfix-2.3-20060403
This commit is contained in:
committed by
Viktor Dukhovni
parent
303c7c57dd
commit
ee4ef8eeb6
@@ -12064,6 +12064,34 @@ Apologies for any names omitted.
|
|||||||
test. A filter timeout was mis-reported as lost connection.
|
test. A filter timeout was mis-reported as lost connection.
|
||||||
Found in code review. File: smtpd/smtpd_proxy.c.
|
Found in code review. File: smtpd/smtpd_proxy.c.
|
||||||
|
|
||||||
|
20060327
|
||||||
|
|
||||||
|
Cleanup: the SQL and LDAP clients now log a warning when
|
||||||
|
they skip an empty lookup result, so that humans don't have
|
||||||
|
to wonder why Postfix doesn't find all the database entries.
|
||||||
|
File: global/db_common.c.
|
||||||
|
|
||||||
|
20060328
|
||||||
|
|
||||||
|
Feature: configurable chroot directive for the pipe(8)
|
||||||
|
delivery agent, by Przemyslaw Wegrzyn. Files:
|
||||||
|
global/pipe_command.c, pipe/pipe.c.
|
||||||
|
|
||||||
|
Bugfix: cut-and-paste error: lmtp_connection_cache_limit
|
||||||
|
was left with the name of smtp_connection_cache_limit.
|
||||||
|
Reported by Victor? File: src/global/mail_params.h.
|
||||||
|
|
||||||
|
20060403
|
||||||
|
|
||||||
|
Cleanup: made fcntl/flock handling consistent with respect
|
||||||
|
to EINTR (reported by Carlo Contavalli). However, Postfix
|
||||||
|
is not meant to be signal safe. Only the master daemon
|
||||||
|
handles signals without terminating, and it uses only a
|
||||||
|
small subset of Postfix library routines. File: util/myflock.c.
|
||||||
|
|
||||||
|
Bugfix: the pipe-to-command error message was lost when the
|
||||||
|
command could not be executed. File: global/pipe_command.c.
|
||||||
|
|
||||||
Wish list:
|
Wish list:
|
||||||
|
|
||||||
Don't send xforward attributes to every site that announces
|
Don't send xforward attributes to every site that announces
|
||||||
|
@@ -181,11 +181,17 @@ that the Postfix queue is under /var/spool/postfix/.
|
|||||||
|
|
||||||
/some/where/dovecot.conf:
|
/some/where/dovecot.conf:
|
||||||
auth default {
|
auth default {
|
||||||
..
|
mechanisms = plain login
|
||||||
|
passdb pam {
|
||||||
|
}
|
||||||
|
userdb passwd {
|
||||||
|
}
|
||||||
socket listen {
|
socket listen {
|
||||||
client {
|
client {
|
||||||
path = /var/spool/postfix/private/auth
|
path = /var/spool/postfix/private/auth
|
||||||
mode = 0666
|
mode = 0660
|
||||||
|
user = postfix
|
||||||
|
group = postfix
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -447,7 +453,7 @@ CCrreeddiittss
|
|||||||
reject_authenticated_sender_login_mismatch and
|
reject_authenticated_sender_login_mismatch and
|
||||||
reject_unauthenticated_sender_login_mismatch, and revised the docs.
|
reject_unauthenticated_sender_login_mismatch, and revised the docs.
|
||||||
* Wietse made another iteration through the code to add plug-in support for
|
* Wietse made another iteration through the code to add plug-in support for
|
||||||
multiple implementations.
|
multiple SASL implementations.
|
||||||
* The Dovecot SMTP server plug-in was originally implemented by Timo Sirainen
|
* The Dovecot SMTP server-only plug-in was originally implemented by Timo
|
||||||
of Procontrol, Finland.
|
Sirainen of Procontrol, Finland.
|
||||||
|
|
||||||
|
@@ -140,7 +140,7 @@ in the Postfix top-level directory: </p>
|
|||||||
|
|
||||||
<li> <p> The "-DDEF_SASL_SERVER" stuff is not necessary; it just
|
<li> <p> The "-DDEF_SASL_SERVER" stuff is not necessary; it just
|
||||||
makes Postfix configuration a little more convenient because you
|
makes Postfix configuration a little more convenient because you
|
||||||
don't have to specify the SASL plug-in type in the Postfix main.cf
|
don't have to specify the SASL plug-in type in the Postfix <a href="postconf.5.html">main.cf</a>
|
||||||
file. </p>
|
file. </p>
|
||||||
|
|
||||||
<li> <p> If you also want support for LDAP or TLS, you will have to merge
|
<li> <p> If you also want support for LDAP or TLS, you will have to merge
|
||||||
@@ -229,7 +229,7 @@ SMTP server</a></h2>
|
|||||||
|
|
||||||
<blockquote>
|
<blockquote>
|
||||||
<pre>
|
<pre>
|
||||||
/etc/postfix/main.cf:
|
/etc/postfix/<a href="postconf.5.html">main.cf</a>:
|
||||||
<a href="postconf.5.html#smtpd_sasl_auth_enable">smtpd_sasl_auth_enable</a> = yes
|
<a href="postconf.5.html#smtpd_sasl_auth_enable">smtpd_sasl_auth_enable</a> = yes
|
||||||
</pre>
|
</pre>
|
||||||
</blockquote>
|
</blockquote>
|
||||||
@@ -238,7 +238,7 @@ SMTP server</a></h2>
|
|||||||
|
|
||||||
<blockquote>
|
<blockquote>
|
||||||
<pre>
|
<pre>
|
||||||
/etc/postfix/main.cf:
|
/etc/postfix/<a href="postconf.5.html">main.cf</a>:
|
||||||
<a href="postconf.5.html#smtpd_recipient_restrictions">smtpd_recipient_restrictions</a> =
|
<a href="postconf.5.html#smtpd_recipient_restrictions">smtpd_recipient_restrictions</a> =
|
||||||
<a href="postconf.5.html#permit_mynetworks">permit_mynetworks</a> <a href="postconf.5.html#permit_sasl_authenticated">permit_sasl_authenticated</a> ...
|
<a href="postconf.5.html#permit_mynetworks">permit_mynetworks</a> <a href="postconf.5.html#permit_sasl_authenticated">permit_sasl_authenticated</a> ...
|
||||||
</pre>
|
</pre>
|
||||||
@@ -249,7 +249,7 @@ SMTP server</a></h2>
|
|||||||
|
|
||||||
<blockquote>
|
<blockquote>
|
||||||
<pre>
|
<pre>
|
||||||
/etc/postfix/main.cf:
|
/etc/postfix/<a href="postconf.5.html">main.cf</a>:
|
||||||
<a href="postconf.5.html#smtpd_sasl_authenticated_header">smtpd_sasl_authenticated_header</a> = yes
|
<a href="postconf.5.html#smtpd_sasl_authenticated_header">smtpd_sasl_authenticated_header</a> = yes
|
||||||
</pre>
|
</pre>
|
||||||
</blockquote>
|
</blockquote>
|
||||||
@@ -265,7 +265,7 @@ clients) use the following: </p>
|
|||||||
|
|
||||||
<blockquote>
|
<blockquote>
|
||||||
<pre>
|
<pre>
|
||||||
/etc/postfix/main.cf:
|
/etc/postfix/<a href="postconf.5.html">main.cf</a>:
|
||||||
<a href="postconf.5.html#broken_sasl_auth_clients">broken_sasl_auth_clients</a> = yes
|
<a href="postconf.5.html#broken_sasl_auth_clients">broken_sasl_auth_clients</a> = yes
|
||||||
</pre>
|
</pre>
|
||||||
</blockquote>
|
</blockquote>
|
||||||
@@ -281,7 +281,7 @@ Postfix runs chrooted: </p>
|
|||||||
|
|
||||||
<blockquote>
|
<blockquote>
|
||||||
<pre>
|
<pre>
|
||||||
/etc/postfix/main.cf:
|
/etc/postfix/<a href="postconf.5.html">main.cf</a>:
|
||||||
<a href="postconf.5.html#smtpd_sasl_type">smtpd_sasl_type</a> = dovecot
|
<a href="postconf.5.html#smtpd_sasl_type">smtpd_sasl_type</a> = dovecot
|
||||||
<a href="postconf.5.html#smtpd_sasl_path">smtpd_sasl_path</a> = private/auth
|
<a href="postconf.5.html#smtpd_sasl_path">smtpd_sasl_path</a> = private/auth
|
||||||
</pre>
|
</pre>
|
||||||
@@ -296,11 +296,17 @@ Postfix queue is under /var/spool/postfix/. </p>
|
|||||||
<pre>
|
<pre>
|
||||||
/some/where/dovecot.conf:
|
/some/where/dovecot.conf:
|
||||||
auth default {
|
auth default {
|
||||||
..
|
mechanisms = plain login
|
||||||
|
passdb pam {
|
||||||
|
}
|
||||||
|
userdb passwd {
|
||||||
|
}
|
||||||
socket listen {
|
socket listen {
|
||||||
client {
|
client {
|
||||||
path = /var/spool/postfix/private/auth
|
path = /var/spool/postfix/private/auth
|
||||||
mode = 0666
|
mode = 0660
|
||||||
|
user = postfix
|
||||||
|
group = postfix
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -352,7 +358,7 @@ library for configuration can be set with: </p>
|
|||||||
|
|
||||||
<blockquote>
|
<blockquote>
|
||||||
<pre>
|
<pre>
|
||||||
/etc/postfix/main.cf:
|
/etc/postfix/<a href="postconf.5.html">main.cf</a>:
|
||||||
smtpd_sasl_application_name = smtpd
|
smtpd_sasl_application_name = smtpd
|
||||||
</pre>
|
</pre>
|
||||||
</blockquote>
|
</blockquote>
|
||||||
@@ -449,7 +455,7 @@ realm used by smtpd: </p>
|
|||||||
|
|
||||||
<blockquote>
|
<blockquote>
|
||||||
<pre>
|
<pre>
|
||||||
/etc/postfix/main.cf:
|
/etc/postfix/<a href="postconf.5.html">main.cf</a>:
|
||||||
<a href="postconf.5.html#smtpd_sasl_local_domain">smtpd_sasl_local_domain</a> = $<a href="postconf.5.html#myhostname">myhostname</a>
|
<a href="postconf.5.html#smtpd_sasl_local_domain">smtpd_sasl_local_domain</a> = $<a href="postconf.5.html#myhostname">myhostname</a>
|
||||||
</pre>
|
</pre>
|
||||||
</blockquote>
|
</blockquote>
|
||||||
@@ -593,7 +599,7 @@ table. </p>
|
|||||||
|
|
||||||
<blockquote>
|
<blockquote>
|
||||||
<pre>
|
<pre>
|
||||||
/etc/postfix/main.cf:
|
/etc/postfix/<a href="postconf.5.html">main.cf</a>:
|
||||||
<a href="postconf.5.html#smtp_sasl_auth_enable">smtp_sasl_auth_enable</a> = yes
|
<a href="postconf.5.html#smtp_sasl_auth_enable">smtp_sasl_auth_enable</a> = yes
|
||||||
<a href="postconf.5.html#smtp_sasl_password_maps">smtp_sasl_password_maps</a> = hash:/etc/postfix/sasl_passwd
|
<a href="postconf.5.html#smtp_sasl_password_maps">smtp_sasl_password_maps</a> = hash:/etc/postfix/sasl_passwd
|
||||||
<a href="postconf.5.html#smtp_sasl_type">smtp_sasl_type</a> = cyrus
|
<a href="postconf.5.html#smtp_sasl_type">smtp_sasl_type</a> = cyrus
|
||||||
@@ -612,7 +618,7 @@ before it searches by destination, specify: </p>
|
|||||||
|
|
||||||
<blockquote>
|
<blockquote>
|
||||||
<pre>
|
<pre>
|
||||||
/etc/postfix/main.cf:
|
/etc/postfix/<a href="postconf.5.html">main.cf</a>:
|
||||||
<a href="postconf.5.html#smtp_sender_dependent_authentication">smtp_sender_dependent_authentication</a> = yes
|
<a href="postconf.5.html#smtp_sender_dependent_authentication">smtp_sender_dependent_authentication</a> = yes
|
||||||
<a href="postconf.5.html#smtp_sasl_auth_enable">smtp_sasl_auth_enable</a> = yes
|
<a href="postconf.5.html#smtp_sasl_auth_enable">smtp_sasl_auth_enable</a> = yes
|
||||||
<a href="postconf.5.html#smtp_sasl_password_maps">smtp_sasl_password_maps</a> = hash:/etc/postfix/sasl_passwd
|
<a href="postconf.5.html#smtp_sasl_password_maps">smtp_sasl_password_maps</a> = hash:/etc/postfix/sasl_passwd
|
||||||
@@ -634,7 +640,7 @@ for example: </p>
|
|||||||
|
|
||||||
<blockquote>
|
<blockquote>
|
||||||
<pre>
|
<pre>
|
||||||
/etc/postfix/main.cf:
|
/etc/postfix/<a href="postconf.5.html">main.cf</a>:
|
||||||
<a href="postconf.5.html#smtp_sasl_security_options">smtp_sasl_security_options</a> = noanonymous
|
<a href="postconf.5.html#smtp_sasl_security_options">smtp_sasl_security_options</a> = noanonymous
|
||||||
</pre>
|
</pre>
|
||||||
</blockquote>
|
</blockquote>
|
||||||
@@ -652,7 +658,7 @@ into consideration: </p>
|
|||||||
|
|
||||||
<blockquote>
|
<blockquote>
|
||||||
<pre>
|
<pre>
|
||||||
/etc/postfix/main.cf:
|
/etc/postfix/<a href="postconf.5.html">main.cf</a>:
|
||||||
<a href="postconf.5.html#smtp_sasl_mechanism_filter">smtp_sasl_mechanism_filter</a> = !gssapi, !external, static:all
|
<a href="postconf.5.html#smtp_sasl_mechanism_filter">smtp_sasl_mechanism_filter</a> = !gssapi, !external, static:all
|
||||||
</pre>
|
</pre>
|
||||||
</blockquote>
|
</blockquote>
|
||||||
@@ -682,9 +688,9 @@ of SuSE Rhein/Main AG.
|
|||||||
<a href="postconf.5.html#reject_unauthenticated_sender_login_mismatch">reject_unauthenticated_sender_login_mismatch</a>, and revised the docs.
|
<a href="postconf.5.html#reject_unauthenticated_sender_login_mismatch">reject_unauthenticated_sender_login_mismatch</a>, and revised the docs.
|
||||||
|
|
||||||
<li> Wietse made another iteration through the code to add
|
<li> Wietse made another iteration through the code to add
|
||||||
plug-in support for multiple implementations.
|
plug-in support for multiple SASL implementations.
|
||||||
|
|
||||||
<li> The Dovecot SMTP server plug-in was originally implemented by
|
<li> The Dovecot SMTP server-only plug-in was originally implemented by
|
||||||
Timo Sirainen of Procontrol, Finland.
|
Timo Sirainen of Procontrol, Finland.
|
||||||
|
|
||||||
</ul>
|
</ul>
|
||||||
|
@@ -48,9 +48,22 @@ PIPE(8) PIPE(8)
|
|||||||
file at the end of a service definition. The syntax is as
|
file at the end of a service definition. The syntax is as
|
||||||
follows:
|
follows:
|
||||||
|
|
||||||
<b>directory=</b><i>pathname</i> (optional, default: <b>$<a href="postconf.5.html#queue_directory">queue_directory</a></b>)
|
<b>chroot=</b><i>pathname</i> (optional)
|
||||||
Change to the named directory before executing the
|
Change the process root directory and working
|
||||||
external command. Delivery is deferred in case of
|
directory to the named directory. This happens
|
||||||
|
before switching to the privileges specified with
|
||||||
|
the <b>user</b> attribute, and before executing the
|
||||||
|
optional <b>directory=</b><i>pathname</i> directive. Delivery is
|
||||||
|
deferred in case of failure.
|
||||||
|
|
||||||
|
This feature is available as of Postfix 2.3.
|
||||||
|
|
||||||
|
<b>directory=</b><i>pathname</i> (optional)
|
||||||
|
Change to the named directory before executing the
|
||||||
|
external command. The directory must be accessible
|
||||||
|
for the user specified with the <b>user</b> attribute (see
|
||||||
|
below). The default working directory is
|
||||||
|
<b>$<a href="postconf.5.html#queue_directory">queue_directory</a></b>. Delivery is deferred in case of
|
||||||
failure.
|
failure.
|
||||||
|
|
||||||
This feature is available as of Postfix 2.2.
|
This feature is available as of Postfix 2.2.
|
||||||
@@ -162,9 +175,9 @@ PIPE(8) PIPE(8)
|
|||||||
<b>user</b>=<i>username</i> (required)
|
<b>user</b>=<i>username</i> (required)
|
||||||
|
|
||||||
<b>user</b>=<i>username</i>:<i>groupname</i>
|
<b>user</b>=<i>username</i>:<i>groupname</i>
|
||||||
The external command is executed with the rights of
|
Execute the external command with the rights of the
|
||||||
the specified <i>username</i>. The software refuses to
|
specified <i>username</i>. The software refuses to exe-
|
||||||
execute commands with root privileges, or with the
|
cute commands with root privileges, or with the
|
||||||
privileges of the mail system owner. If <i>groupname</i>
|
privileges of the mail system owner. If <i>groupname</i>
|
||||||
is specified, the corresponding group ID is used
|
is specified, the corresponding group ID is used
|
||||||
instead of the group ID of <i>username</i>.
|
instead of the group ID of <i>username</i>.
|
||||||
|
@@ -3154,6 +3154,18 @@ configuration parameter. See there for details. </p>
|
|||||||
<p> This feature is available in Postfix 2.3 and later. </p>
|
<p> This feature is available in Postfix 2.3 and later. </p>
|
||||||
|
|
||||||
|
|
||||||
|
</DD>
|
||||||
|
|
||||||
|
<DT><b><a name="lmtp_connection_cache_time_limit">lmtp_connection_cache_time_limit</a>
|
||||||
|
(default: 2s)</b></DT><DD>
|
||||||
|
|
||||||
|
<p> The LMTP-specific version of the
|
||||||
|
<a href="postconf.5.html#smtp_connection_cache_time_limit">smtp_connection_cache_time_limit</a> configuration parameter.
|
||||||
|
See there for details. </p>
|
||||||
|
|
||||||
|
<p> This feature is available in Postfix 2.3 and later. </p>
|
||||||
|
|
||||||
|
|
||||||
</DD>
|
</DD>
|
||||||
|
|
||||||
<DT><b><a name="lmtp_connection_reuse_time_limit">lmtp_connection_reuse_time_limit</a>
|
<DT><b><a name="lmtp_connection_reuse_time_limit">lmtp_connection_reuse_time_limit</a>
|
||||||
|
@@ -1705,6 +1705,12 @@ The LMTP-specific version of the smtp_connection_cache_on_demand
|
|||||||
configuration parameter. See there for details.
|
configuration parameter. See there for details.
|
||||||
.PP
|
.PP
|
||||||
This feature is available in Postfix 2.3 and later.
|
This feature is available in Postfix 2.3 and later.
|
||||||
|
.SH lmtp_connection_cache_time_limit (default: 2s)
|
||||||
|
The LMTP-specific version of the
|
||||||
|
smtp_connection_cache_time_limit configuration parameter.
|
||||||
|
See there for details.
|
||||||
|
.PP
|
||||||
|
This feature is available in Postfix 2.3 and later.
|
||||||
.SH lmtp_connection_reuse_time_limit (default: 300s)
|
.SH lmtp_connection_reuse_time_limit (default: 300s)
|
||||||
The LMTP-specific version of the smtp_connection_reuse_time_limit
|
The LMTP-specific version of the smtp_connection_reuse_time_limit
|
||||||
configuration parameter. See there for details.
|
configuration parameter. See there for details.
|
||||||
|
@@ -51,8 +51,19 @@ entry for the pipe-based delivery transport.
|
|||||||
.fi
|
.fi
|
||||||
The external command attributes are given in the \fBmaster.cf\fR
|
The external command attributes are given in the \fBmaster.cf\fR
|
||||||
file at the end of a service definition. The syntax is as follows:
|
file at the end of a service definition. The syntax is as follows:
|
||||||
.IP "\fBdirectory=\fIpathname\fR (optional, default: \fB$queue_directory\fR)"
|
.IP "\fBchroot=\fIpathname\fR (optional)"
|
||||||
|
Change the process root directory and working directory to
|
||||||
|
the named directory. This happens before switching to the
|
||||||
|
privileges specified with the \fBuser\fR attribute, and
|
||||||
|
before executing the optional \fBdirectory=\fIpathname\fR
|
||||||
|
directive. Delivery is deferred in case of failure.
|
||||||
|
.sp
|
||||||
|
This feature is available as of Postfix 2.3.
|
||||||
|
.IP "\fBdirectory=\fIpathname\fR (optional)"
|
||||||
Change to the named directory before executing the external command.
|
Change to the named directory before executing the external command.
|
||||||
|
The directory must be accessible for the user specified with the
|
||||||
|
\fBuser\fR attribute (see below).
|
||||||
|
The default working directory is \fB$queue_directory\fR.
|
||||||
Delivery is deferred in case of failure.
|
Delivery is deferred in case of failure.
|
||||||
.sp
|
.sp
|
||||||
This feature is available as of Postfix 2.2.
|
This feature is available as of Postfix 2.2.
|
||||||
@@ -148,7 +159,7 @@ Messages greater in size than this limit (in bytes) will
|
|||||||
be returned to the sender as undeliverable.
|
be returned to the sender as undeliverable.
|
||||||
.IP "\fBuser\fR=\fIusername\fR (required)"
|
.IP "\fBuser\fR=\fIusername\fR (required)"
|
||||||
.IP "\fBuser\fR=\fIusername\fR:\fIgroupname\fR"
|
.IP "\fBuser\fR=\fIusername\fR:\fIgroupname\fR"
|
||||||
The external command is executed with the rights of the
|
Execute the external command with the rights of the
|
||||||
specified \fIusername\fR. The software refuses to execute
|
specified \fIusername\fR. The software refuses to execute
|
||||||
commands with root privileges, or with the privileges of the
|
commands with root privileges, or with the privileges of the
|
||||||
mail system owner. If \fIgroupname\fR is specified, the
|
mail system owner. If \fIgroupname\fR is specified, the
|
||||||
|
@@ -201,6 +201,7 @@ while (<>) {
|
|||||||
s;\blmtp_sasl_mechanism_filter\b;<a href="postconf.5.html#lmtp_sasl_mechanism_filter">$&</a>;g;
|
s;\blmtp_sasl_mechanism_filter\b;<a href="postconf.5.html#lmtp_sasl_mechanism_filter">$&</a>;g;
|
||||||
s;\blmtp_host_lookup\b;<a href="postconf.5.html#lmtp_host_lookup">$&</a>;g;
|
s;\blmtp_host_lookup\b;<a href="postconf.5.html#lmtp_host_lookup">$&</a>;g;
|
||||||
s;\blmtp_connection_cache_destinations\b;<a href="postconf.5.html#lmtp_connection_cache_destinations">$&</a>;g;
|
s;\blmtp_connection_cache_destinations\b;<a href="postconf.5.html#lmtp_connection_cache_destinations">$&</a>;g;
|
||||||
|
s;\blmtp_connection_cache_time_limit\b;<a href="postconf.5.html#lmtp_connection_cache_time_limit">$&</a>;g;
|
||||||
s;\blmtp_tls_per_site\b;<a href="postconf.5.html#lmtp_tls_per_site">$&</a>;g;
|
s;\blmtp_tls_per_site\b;<a href="postconf.5.html#lmtp_tls_per_site">$&</a>;g;
|
||||||
s;\blmtp_generic_maps\b;<a href="postconf.5.html#lmtp_generic_maps">$&</a>;g;
|
s;\blmtp_generic_maps\b;<a href="postconf.5.html#lmtp_generic_maps">$&</a>;g;
|
||||||
s;\blmtp_pix_workaround_threshold_time\b;<a href="postconf.5.html#lmtp_pix_workaround_threshold_time">$&</a>;g;
|
s;\blmtp_pix_workaround_threshold_time\b;<a href="postconf.5.html#lmtp_pix_workaround_threshold_time">$&</a>;g;
|
||||||
|
@@ -296,11 +296,17 @@ Postfix queue is under /var/spool/postfix/. </p>
|
|||||||
<pre>
|
<pre>
|
||||||
/some/where/dovecot.conf:
|
/some/where/dovecot.conf:
|
||||||
auth default {
|
auth default {
|
||||||
..
|
mechanisms = plain login
|
||||||
|
passdb pam {
|
||||||
|
}
|
||||||
|
userdb passwd {
|
||||||
|
}
|
||||||
socket listen {
|
socket listen {
|
||||||
client {
|
client {
|
||||||
path = /var/spool/postfix/private/auth
|
path = /var/spool/postfix/private/auth
|
||||||
mode = 0666
|
mode = 0660
|
||||||
|
user = postfix
|
||||||
|
group = postfix
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -682,9 +688,9 @@ reject_authenticated_sender_login_mismatch and
|
|||||||
reject_unauthenticated_sender_login_mismatch, and revised the docs.
|
reject_unauthenticated_sender_login_mismatch, and revised the docs.
|
||||||
|
|
||||||
<li> Wietse made another iteration through the code to add
|
<li> Wietse made another iteration through the code to add
|
||||||
plug-in support for multiple implementations.
|
plug-in support for multiple SASL implementations.
|
||||||
|
|
||||||
<li> The Dovecot SMTP server plug-in was originally implemented by
|
<li> The Dovecot SMTP server-only plug-in was originally implemented by
|
||||||
Timo Sirainen of Procontrol, Finland.
|
Timo Sirainen of Procontrol, Finland.
|
||||||
|
|
||||||
</ul>
|
</ul>
|
||||||
|
@@ -9243,6 +9243,14 @@ See there for details. </p>
|
|||||||
|
|
||||||
<p> This feature is available in Postfix 2.3 and later. </p>
|
<p> This feature is available in Postfix 2.3 and later. </p>
|
||||||
|
|
||||||
|
%PARAM lmtp_connection_cache_time_limit 2s
|
||||||
|
|
||||||
|
<p> The LMTP-specific version of the
|
||||||
|
smtp_connection_cache_time_limit configuration parameter.
|
||||||
|
See there for details. </p>
|
||||||
|
|
||||||
|
<p> This feature is available in Postfix 2.3 and later. </p>
|
||||||
|
|
||||||
%PARAM smtpd_delay_open_until_valid_rcpt yes
|
%PARAM smtpd_delay_open_until_valid_rcpt yes
|
||||||
|
|
||||||
<p> Postpone the start of an SMTP mail transaction until a valid
|
<p> Postpone the start of an SMTP mail transaction until a valid
|
||||||
|
@@ -1415,10 +1415,12 @@ own_inet_addr.o: mail_params.h
|
|||||||
own_inet_addr.o: own_inet_addr.c
|
own_inet_addr.o: own_inet_addr.c
|
||||||
own_inet_addr.o: own_inet_addr.h
|
own_inet_addr.o: own_inet_addr.h
|
||||||
pipe_command.o: ../../include/argv.h
|
pipe_command.o: ../../include/argv.h
|
||||||
|
pipe_command.o: ../../include/chroot_uid.h
|
||||||
pipe_command.o: ../../include/clean_env.h
|
pipe_command.o: ../../include/clean_env.h
|
||||||
pipe_command.o: ../../include/exec_command.h
|
pipe_command.o: ../../include/exec_command.h
|
||||||
pipe_command.o: ../../include/iostuff.h
|
pipe_command.o: ../../include/iostuff.h
|
||||||
pipe_command.o: ../../include/msg.h
|
pipe_command.o: ../../include/msg.h
|
||||||
|
pipe_command.o: ../../include/msg_vstream.h
|
||||||
pipe_command.o: ../../include/set_eugid.h
|
pipe_command.o: ../../include/set_eugid.h
|
||||||
pipe_command.o: ../../include/set_ugid.h
|
pipe_command.o: ../../include/set_ugid.h
|
||||||
pipe_command.o: ../../include/stringops.h
|
pipe_command.o: ../../include/stringops.h
|
||||||
|
@@ -278,7 +278,7 @@ int db_common_expand(void *ctxArg, const char *format, const char *value,
|
|||||||
db_quote_callback_t quote_func)
|
db_quote_callback_t quote_func)
|
||||||
{
|
{
|
||||||
char *myname = "db_common_expand";
|
char *myname = "db_common_expand";
|
||||||
DB_COMMON_CTX *ctx = (DB_COMMON_CTX *)ctxArg;
|
DB_COMMON_CTX *ctx = (DB_COMMON_CTX *) ctxArg;
|
||||||
const char *vdomain = 0;
|
const char *vdomain = 0;
|
||||||
const char *kdomain = 0;
|
const char *kdomain = 0;
|
||||||
char *vuser = 0;
|
char *vuser = 0;
|
||||||
@@ -287,18 +287,28 @@ int db_common_expand(void *ctxArg, const char *format, const char *value,
|
|||||||
int i;
|
int i;
|
||||||
const char *cp;
|
const char *cp;
|
||||||
|
|
||||||
/* Skip NULL or empty values */
|
/* Skip NULL values, silently. */
|
||||||
if (value == 0 || *value == 0)
|
if (value == 0)
|
||||||
return (0);
|
return (0);
|
||||||
|
|
||||||
|
/* Don't silenty skip empty query string or empty lookup results. */
|
||||||
|
if (*value == 0) {
|
||||||
|
if (key)
|
||||||
|
msg_warn("table \"%s:%s\": empty lookup result for: \"%s\""
|
||||||
|
" -- ignored", ctx->dict->type, ctx->dict->name, key);
|
||||||
|
else
|
||||||
|
msg_warn("table \"%s:%s\": empty query string"
|
||||||
|
" -- ignored", ctx->dict->type, ctx->dict->name);
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
if (key) {
|
if (key) {
|
||||||
/* This is a result template and the input value is the result */
|
/* This is a result template and the input value is the result */
|
||||||
if (ctx->flags & (DB_COMMON_VALUE_DOMAIN | DB_COMMON_VALUE_USER))
|
if (ctx->flags & (DB_COMMON_VALUE_DOMAIN | DB_COMMON_VALUE_USER))
|
||||||
if ((vdomain = strrchr(value, '@')) != 0)
|
if ((vdomain = strrchr(value, '@')) != 0)
|
||||||
++vdomain;
|
++vdomain;
|
||||||
|
|
||||||
if ((!vdomain || !*vdomain) && (ctx->flags&DB_COMMON_VALUE_DOMAIN) != 0
|
if ((!vdomain || !*vdomain) && (ctx->flags & DB_COMMON_VALUE_DOMAIN) != 0
|
||||||
|| vdomain == value + 1 && (ctx->flags&DB_COMMON_VALUE_USER) != 0)
|
|| vdomain == value + 1 && (ctx->flags & DB_COMMON_VALUE_USER) != 0)
|
||||||
return (0);
|
return (0);
|
||||||
|
|
||||||
/* The result format may use the local or domain part of the key */
|
/* The result format may use the local or domain part of the key */
|
||||||
@@ -307,50 +317,51 @@ int db_common_expand(void *ctxArg, const char *format, const char *value,
|
|||||||
++kdomain;
|
++kdomain;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The key should already be checked before the query. No harm if
|
* The key should already be checked before the query. No harm if the
|
||||||
* the query did not get optimized out, so we just issue a warning.
|
* query did not get optimized out, so we just issue a warning.
|
||||||
*/
|
*/
|
||||||
if ((!kdomain || !*kdomain) && (ctx->flags&DB_COMMON_KEY_DOMAIN) != 0
|
if ((!kdomain || !*kdomain) && (ctx->flags & DB_COMMON_KEY_DOMAIN) != 0
|
||||||
|| kdomain == key + 1 && (ctx->flags & DB_COMMON_KEY_USER) != 0) {
|
|| kdomain == key + 1 && (ctx->flags & DB_COMMON_KEY_USER) != 0) {
|
||||||
msg_warn("%s: %s: lookup key '%s' skipped after query", myname,
|
msg_warn("%s: %s: lookup key '%s' skipped after query", myname,
|
||||||
ctx->dict->name, value);
|
ctx->dict->name, value);
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* This is a query template and the input value is the lookup key */
|
/* This is a query template and the input value is the lookup key */
|
||||||
if (ctx->flags & (DB_COMMON_KEY_DOMAIN | DB_COMMON_KEY_USER))
|
if (ctx->flags & (DB_COMMON_KEY_DOMAIN | DB_COMMON_KEY_USER))
|
||||||
if ((vdomain = strrchr(value, '@')) != 0)
|
if ((vdomain = strrchr(value, '@')) != 0)
|
||||||
++vdomain;
|
++vdomain;
|
||||||
|
|
||||||
if ((!vdomain || !*vdomain) && (ctx->flags&DB_COMMON_KEY_DOMAIN) != 0
|
if ((!vdomain || !*vdomain) && (ctx->flags & DB_COMMON_KEY_DOMAIN) != 0
|
||||||
|| vdomain == value + 1 && (ctx->flags & DB_COMMON_KEY_USER) != 0)
|
|| vdomain == value + 1 && (ctx->flags & DB_COMMON_KEY_USER) != 0)
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ctx->nparts > 0) {
|
if (ctx->nparts > 0) {
|
||||||
parts = argv_split(key ? kdomain : vdomain, ".");
|
parts = argv_split(key ? kdomain : vdomain, ".");
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Filter out input keys whose domains lack enough labels
|
* Filter out input keys whose domains lack enough labels to fill-in
|
||||||
* to fill-in the query template. See below and also
|
* the query template. See below and also db_common_parse() which
|
||||||
* db_common_parse() which initializes ctx->nparts.
|
* initializes ctx->nparts.
|
||||||
*/
|
*/
|
||||||
if (parts->argc < ctx->nparts) {
|
if (parts->argc < ctx->nparts) {
|
||||||
argv_free(parts);
|
argv_free(parts);
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Skip domains with leading, consecutive or trailing '.'
|
* Skip domains with leading, consecutive or trailing '.' separators
|
||||||
* separators among the required labels.
|
* among the required labels.
|
||||||
*/
|
*/
|
||||||
for (i = 0; i < ctx->nparts; i++)
|
for (i = 0; i < ctx->nparts; i++)
|
||||||
if (*parts->argv[parts->argc-i-1] == 0) {
|
if (*parts->argv[parts->argc - i - 1] == 0) {
|
||||||
argv_free(parts);
|
argv_free(parts);
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (VSTRING_LEN(result) > 0)
|
if (VSTRING_LEN(result) > 0)
|
||||||
VSTRING_ADDCH(result, ',');
|
VSTRING_ADDCH(result, ',');
|
||||||
|
|
||||||
#define QUOTE_VAL(d, q, v, buf) do { \
|
#define QUOTE_VAL(d, q, v, buf) do { \
|
||||||
if (q) \
|
if (q) \
|
||||||
@@ -360,9 +371,9 @@ int db_common_expand(void *ctxArg, const char *format, const char *value,
|
|||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Replace all instances of %s with the address to look up. Replace
|
* Replace all instances of %s with the address to look up. Replace %u
|
||||||
* %u with the user portion, and %d with the domain portion. "%%"
|
* with the user portion, and %d with the domain portion. "%%" expands to
|
||||||
* expands to "%". lowercase -> addr, uppercase -> key
|
* "%". lowercase -> addr, uppercase -> key
|
||||||
*/
|
*/
|
||||||
for (cp = format; *cp; cp++) {
|
for (cp = format; *cp; cp++) {
|
||||||
if (*cp == '%') {
|
if (*cp == '%') {
|
||||||
@@ -381,8 +392,7 @@ int db_common_expand(void *ctxArg, const char *format, const char *value,
|
|||||||
if (vuser == 0)
|
if (vuser == 0)
|
||||||
vuser = mystrndup(value, vdomain - value - 1);
|
vuser = mystrndup(value, vdomain - value - 1);
|
||||||
QUOTE_VAL(ctx->dict, quote_func, vuser, result);
|
QUOTE_VAL(ctx->dict, quote_func, vuser, result);
|
||||||
}
|
} else
|
||||||
else
|
|
||||||
QUOTE_VAL(ctx->dict, quote_func, value, result);
|
QUOTE_VAL(ctx->dict, quote_func, value, result);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -391,7 +401,7 @@ int db_common_expand(void *ctxArg, const char *format, const char *value,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 'S':
|
case 'S':
|
||||||
if (key)
|
if (key)
|
||||||
QUOTE_VAL(ctx->dict, quote_func, key, result);
|
QUOTE_VAL(ctx->dict, quote_func, key, result);
|
||||||
else
|
else
|
||||||
QUOTE_VAL(ctx->dict, quote_func, value, result);
|
QUOTE_VAL(ctx->dict, quote_func, value, result);
|
||||||
@@ -403,16 +413,14 @@ int db_common_expand(void *ctxArg, const char *format, const char *value,
|
|||||||
if (kuser == 0)
|
if (kuser == 0)
|
||||||
kuser = mystrndup(key, kdomain - key - 1);
|
kuser = mystrndup(key, kdomain - key - 1);
|
||||||
QUOTE_VAL(ctx->dict, quote_func, kuser, result);
|
QUOTE_VAL(ctx->dict, quote_func, kuser, result);
|
||||||
}
|
} else
|
||||||
else
|
|
||||||
QUOTE_VAL(ctx->dict, quote_func, key, result);
|
QUOTE_VAL(ctx->dict, quote_func, key, result);
|
||||||
} else {
|
} else {
|
||||||
if (vdomain) {
|
if (vdomain) {
|
||||||
if (vuser == 0)
|
if (vuser == 0)
|
||||||
vuser = mystrndup(value, vdomain - value - 1);
|
vuser = mystrndup(value, vdomain - value - 1);
|
||||||
QUOTE_VAL(ctx->dict, quote_func, vuser, result);
|
QUOTE_VAL(ctx->dict, quote_func, vuser, result);
|
||||||
}
|
} else
|
||||||
else
|
|
||||||
QUOTE_VAL(ctx->dict, quote_func, value, result);
|
QUOTE_VAL(ctx->dict, quote_func, value, result);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -424,18 +432,26 @@ int db_common_expand(void *ctxArg, const char *format, const char *value,
|
|||||||
QUOTE_VAL(ctx->dict, quote_func, vdomain, result);
|
QUOTE_VAL(ctx->dict, quote_func, vdomain, result);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case '1': case '2': case '3': case '4': case '5':
|
case '1':
|
||||||
case '6': case '7': case '8': case '9':
|
case '2':
|
||||||
/*
|
case '3':
|
||||||
* Interpolate %[1-9] components into the query string.
|
case '4':
|
||||||
* By this point db_common_parse() has identified the
|
case '5':
|
||||||
* highest component index, and (see above) keys with
|
case '6':
|
||||||
* fewer components have been filtered out. The "parts"
|
case '7':
|
||||||
* ARGV is guaranteed to be initialized and hold enough
|
case '8':
|
||||||
* elements to satisfy the query template.
|
case '9':
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Interpolate %[1-9] components into the query string. By
|
||||||
|
* this point db_common_parse() has identified the highest
|
||||||
|
* component index, and (see above) keys with fewer
|
||||||
|
* components have been filtered out. The "parts" ARGV is
|
||||||
|
* guaranteed to be initialized and hold enough elements to
|
||||||
|
* satisfy the query template.
|
||||||
*/
|
*/
|
||||||
QUOTE_VAL(ctx->dict, quote_func,
|
QUOTE_VAL(ctx->dict, quote_func,
|
||||||
parts->argv[parts->argc-(*cp-'0')], result);
|
parts->argv[parts->argc - (*cp - '0')], result);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@@ -449,11 +465,11 @@ int db_common_expand(void *ctxArg, const char *format, const char *value,
|
|||||||
VSTRING_TERMINATE(result);
|
VSTRING_TERMINATE(result);
|
||||||
|
|
||||||
if (vuser)
|
if (vuser)
|
||||||
myfree(vuser);
|
myfree(vuser);
|
||||||
if (kuser)
|
if (kuser)
|
||||||
myfree(kuser);
|
myfree(kuser);
|
||||||
if (parts)
|
if (parts)
|
||||||
argv_free(parts);
|
argv_free(parts);
|
||||||
|
|
||||||
return (1);
|
return (1);
|
||||||
}
|
}
|
||||||
|
@@ -870,7 +870,7 @@ extern char *var_bestmx_transp;
|
|||||||
|
|
||||||
#define VAR_SMTP_CACHE_CONNT "smtp_connection_cache_time_limit"
|
#define VAR_SMTP_CACHE_CONNT "smtp_connection_cache_time_limit"
|
||||||
#define DEF_SMTP_CACHE_CONNT "2s"
|
#define DEF_SMTP_CACHE_CONNT "2s"
|
||||||
#define VAR_LMTP_CACHE_CONNT "smtp_connection_cache_time_limit"
|
#define VAR_LMTP_CACHE_CONNT "lmtp_connection_cache_time_limit"
|
||||||
#define DEF_LMTP_CACHE_CONNT "2s"
|
#define DEF_LMTP_CACHE_CONNT "2s"
|
||||||
extern int var_smtp_cache_conn;
|
extern int var_smtp_cache_conn;
|
||||||
|
|
||||||
|
@@ -20,7 +20,7 @@
|
|||||||
* Patches change both the patchlevel and the release date. Snapshots have no
|
* Patches change both the patchlevel and the release date. Snapshots have no
|
||||||
* patchlevel; they change the release date only.
|
* patchlevel; they change the release date only.
|
||||||
*/
|
*/
|
||||||
#define MAIL_RELEASE_DATE "20060325"
|
#define MAIL_RELEASE_DATE "20060403"
|
||||||
#define MAIL_VERSION_NUMBER "2.3"
|
#define MAIL_VERSION_NUMBER "2.3"
|
||||||
|
|
||||||
#ifdef SNAPSHOT
|
#ifdef SNAPSHOT
|
||||||
|
@@ -44,8 +44,14 @@
|
|||||||
/* The command is specified as an argument vector. This vector is
|
/* The command is specified as an argument vector. This vector is
|
||||||
/* passed without further inspection to the \fIexecvp\fR() routine.
|
/* passed without further inspection to the \fIexecvp\fR() routine.
|
||||||
/* One of PIPE_CMD_COMMAND or PIPE_CMD_ARGV must be specified.
|
/* One of PIPE_CMD_COMMAND or PIPE_CMD_ARGV must be specified.
|
||||||
|
/* .IP "PIPE_CMD_CHROOT (char *)"
|
||||||
|
/* Root and working directory for command execution. This takes
|
||||||
|
/* effect before PIPE_CMD_CWD. A null pointer means don't
|
||||||
|
/* change root and working directory anyway. Failure to change
|
||||||
|
/* directory causes mail delivery to be deferred.
|
||||||
/* .IP "PIPE_CMD_CWD (char *)"
|
/* .IP "PIPE_CMD_CWD (char *)"
|
||||||
/* Working directory for command execution. A null pointer means
|
/* Working directory for command execution, after changing process
|
||||||
|
/* privileges to PIPE_CMD_UID and PIPE_CMD_GID. A null pointer means
|
||||||
/* don't change directory anyway. Failure to change directory
|
/* don't change directory anyway. Failure to change directory
|
||||||
/* causes mail delivery to be deferred.
|
/* causes mail delivery to be deferred.
|
||||||
/* .IP "PIPE_CMD_ENV (char **)"
|
/* .IP "PIPE_CMD_ENV (char **)"
|
||||||
@@ -137,6 +143,7 @@
|
|||||||
|
|
||||||
#include <msg.h>
|
#include <msg.h>
|
||||||
#include <vstream.h>
|
#include <vstream.h>
|
||||||
|
#include <msg_vstream.h>
|
||||||
#include <vstring.h>
|
#include <vstring.h>
|
||||||
#include <stringops.h>
|
#include <stringops.h>
|
||||||
#include <iostuff.h>
|
#include <iostuff.h>
|
||||||
@@ -144,6 +151,7 @@
|
|||||||
#include <set_ugid.h>
|
#include <set_ugid.h>
|
||||||
#include <set_eugid.h>
|
#include <set_eugid.h>
|
||||||
#include <argv.h>
|
#include <argv.h>
|
||||||
|
#include <chroot_uid.h>
|
||||||
|
|
||||||
/* Global library. */
|
/* Global library. */
|
||||||
|
|
||||||
@@ -172,6 +180,7 @@ struct pipe_args {
|
|||||||
char **export; /* exportable environment */
|
char **export; /* exportable environment */
|
||||||
char *shell; /* command shell */
|
char *shell; /* command shell */
|
||||||
char *cwd; /* preferred working directory */
|
char *cwd; /* preferred working directory */
|
||||||
|
char *chroot; /* root directory */
|
||||||
};
|
};
|
||||||
|
|
||||||
static int pipe_command_timeout; /* command has timed out */
|
static int pipe_command_timeout; /* command has timed out */
|
||||||
@@ -200,6 +209,7 @@ static void get_pipe_args(struct pipe_args * args, va_list ap)
|
|||||||
args->export = 0;
|
args->export = 0;
|
||||||
args->shell = 0;
|
args->shell = 0;
|
||||||
args->cwd = 0;
|
args->cwd = 0;
|
||||||
|
args->chroot = 0;
|
||||||
|
|
||||||
pipe_command_maxtime = var_command_maxtime;
|
pipe_command_maxtime = var_command_maxtime;
|
||||||
|
|
||||||
@@ -254,6 +264,9 @@ static void get_pipe_args(struct pipe_args * args, va_list ap)
|
|||||||
case PIPE_CMD_CWD:
|
case PIPE_CMD_CWD:
|
||||||
args->cwd = va_arg(ap, char *);
|
args->cwd = va_arg(ap, char *);
|
||||||
break;
|
break;
|
||||||
|
case PIPE_CMD_CHROOT:
|
||||||
|
args->chroot = va_arg(ap, char *);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
msg_panic("%s: unknown key: %d", myname, key);
|
msg_panic("%s: unknown key: %d", myname, key);
|
||||||
}
|
}
|
||||||
@@ -357,14 +370,22 @@ static int pipe_command_wait_or_kill(pid_t pid, WAIT_STATUS_T *statusp, int sig,
|
|||||||
|
|
||||||
static void pipe_child_cleanup(void)
|
static void pipe_child_cleanup(void)
|
||||||
{
|
{
|
||||||
exit(EX_TEMPFAIL);
|
|
||||||
|
/*
|
||||||
|
* WARNING: don't place code here. This code may run as mail_owner, as
|
||||||
|
* root, or as the user/group specified with the "user" attribute. The
|
||||||
|
* only safe action is to terminate.
|
||||||
|
*
|
||||||
|
* Future proofing. If you need exit() here then you broke Postfix.
|
||||||
|
*/
|
||||||
|
_exit(EX_TEMPFAIL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* pipe_command - execute command with extreme prejudice */
|
/* pipe_command - execute command with extreme prejudice */
|
||||||
|
|
||||||
int pipe_command(VSTREAM *src, DSN_BUF *why,...)
|
int pipe_command(VSTREAM *src, DSN_BUF *why,...)
|
||||||
{
|
{
|
||||||
char *myname = "pipe_comand";
|
char *myname = "pipe_command";
|
||||||
va_list ap;
|
va_list ap;
|
||||||
VSTREAM *cmd_in_stream;
|
VSTREAM *cmd_in_stream;
|
||||||
VSTREAM *cmd_out_stream;
|
VSTREAM *cmd_out_stream;
|
||||||
@@ -448,6 +469,28 @@ int pipe_command(VSTREAM *src, DSN_BUF *why,...)
|
|||||||
*/
|
*/
|
||||||
case 0:
|
case 0:
|
||||||
(void) msg_cleanup(pipe_child_cleanup);
|
(void) msg_cleanup(pipe_child_cleanup);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* In order to chroot it is necessary to switch euid back to root.
|
||||||
|
* Right after chroot we call set_ugid() so all privileges will be
|
||||||
|
* dropped again.
|
||||||
|
*
|
||||||
|
* XXX For consistency we use chroot_uid() to change root+current
|
||||||
|
* directory. However, we must not use chroot_uid() to change process
|
||||||
|
* privileges (assuming a version that accepts numeric privileges).
|
||||||
|
* That would create a maintenance problem, because we would have two
|
||||||
|
* different code paths to set the external command's privileges.
|
||||||
|
*/
|
||||||
|
if (args.chroot) {
|
||||||
|
seteuid(0);
|
||||||
|
chroot_uid(args.chroot, (char *) 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* XXX If we put code before the set_ugid() call, then the code that
|
||||||
|
* changes root directory must switch back to the mail_owner UID,
|
||||||
|
* otherwise we'd be running with root privileges.
|
||||||
|
*/
|
||||||
set_ugid(args.uid, args.gid);
|
set_ugid(args.uid, args.gid);
|
||||||
if (setsid() < 0)
|
if (setsid() < 0)
|
||||||
msg_warn("setsid failed: %m");
|
msg_warn("setsid failed: %m");
|
||||||
@@ -488,12 +531,15 @@ int pipe_command(VSTREAM *src, DSN_BUF *why,...)
|
|||||||
/*
|
/*
|
||||||
* Process plumbing. If possible, avoid running a shell.
|
* Process plumbing. If possible, avoid running a shell.
|
||||||
*
|
*
|
||||||
* From this point we would like to handle fatal errors ourselves
|
* As a safety for buggy libraries, we close the syslog socket.
|
||||||
* (ENOMEM would probably be one of the few soft error conditions).
|
* Otherwise we could leak a file descriptor that was created by a
|
||||||
* For that we have to update exec_command() first so it returns an
|
* privileged process.
|
||||||
* error indication instead of terminating the process.
|
*
|
||||||
|
* XXX To avoid losing fatal error messages we open a VSTREAM and
|
||||||
|
* capture the output in the parent process.
|
||||||
*/
|
*/
|
||||||
closelog();
|
closelog();
|
||||||
|
msg_vstream_init(var_procname, VSTREAM_ERR);
|
||||||
if (args.argv) {
|
if (args.argv) {
|
||||||
execvp(args.argv[0], args.argv);
|
execvp(args.argv[0], args.argv);
|
||||||
msg_fatal("%s: execvp %s: %m", myname, args.argv[0]);
|
msg_fatal("%s: execvp %s: %m", myname, args.argv[0]);
|
||||||
@@ -605,7 +651,10 @@ int pipe_command(VSTREAM *src, DSN_BUF *why,...)
|
|||||||
return (sp->dsn[0] == '4' ?
|
return (sp->dsn[0] == '4' ?
|
||||||
PIPE_STAT_DEFER : PIPE_STAT_BOUNCE);
|
PIPE_STAT_DEFER : PIPE_STAT_BOUNCE);
|
||||||
}
|
}
|
||||||
/* No "D.S.N text" or <sysexits.h> compatible status. Fake it. */
|
|
||||||
|
/*
|
||||||
|
* No "D.S.N text" or <sysexits.h> compatible status. Fake it.
|
||||||
|
*/
|
||||||
else {
|
else {
|
||||||
sp = sys_exits_detail(WEXITSTATUS(wait_status));
|
sp = sys_exits_detail(WEXITSTATUS(wait_status));
|
||||||
dsb_unix(why, sp->dsn,
|
dsb_unix(why, sp->dsn,
|
||||||
|
@@ -41,6 +41,7 @@
|
|||||||
#define PIPE_CMD_EXPORT 12 /* exportable environment */
|
#define PIPE_CMD_EXPORT 12 /* exportable environment */
|
||||||
#define PIPE_CMD_ORIG_RCPT 13 /* mail_copy() original recipient */
|
#define PIPE_CMD_ORIG_RCPT 13 /* mail_copy() original recipient */
|
||||||
#define PIPE_CMD_CWD 14 /* working directory */
|
#define PIPE_CMD_CWD 14 /* working directory */
|
||||||
|
#define PIPE_CMD_CHROOT 15 /* chroot() before exec() */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Command completion status.
|
* Command completion status.
|
||||||
|
@@ -41,8 +41,19 @@
|
|||||||
/* .fi
|
/* .fi
|
||||||
/* The external command attributes are given in the \fBmaster.cf\fR
|
/* The external command attributes are given in the \fBmaster.cf\fR
|
||||||
/* file at the end of a service definition. The syntax is as follows:
|
/* file at the end of a service definition. The syntax is as follows:
|
||||||
/* .IP "\fBdirectory=\fIpathname\fR (optional, default: \fB$queue_directory\fR)"
|
/* .IP "\fBchroot=\fIpathname\fR (optional)"
|
||||||
|
/* Change the process root directory and working directory to
|
||||||
|
/* the named directory. This happens before switching to the
|
||||||
|
/* privileges specified with the \fBuser\fR attribute, and
|
||||||
|
/* before executing the optional \fBdirectory=\fIpathname\fR
|
||||||
|
/* directive. Delivery is deferred in case of failure.
|
||||||
|
/* .sp
|
||||||
|
/* This feature is available as of Postfix 2.3.
|
||||||
|
/* .IP "\fBdirectory=\fIpathname\fR (optional)"
|
||||||
/* Change to the named directory before executing the external command.
|
/* Change to the named directory before executing the external command.
|
||||||
|
/* The directory must be accessible for the user specified with the
|
||||||
|
/* \fBuser\fR attribute (see below).
|
||||||
|
/* The default working directory is \fB$queue_directory\fR.
|
||||||
/* Delivery is deferred in case of failure.
|
/* Delivery is deferred in case of failure.
|
||||||
/* .sp
|
/* .sp
|
||||||
/* This feature is available as of Postfix 2.2.
|
/* This feature is available as of Postfix 2.2.
|
||||||
@@ -138,7 +149,7 @@
|
|||||||
/* be returned to the sender as undeliverable.
|
/* be returned to the sender as undeliverable.
|
||||||
/* .IP "\fBuser\fR=\fIusername\fR (required)"
|
/* .IP "\fBuser\fR=\fIusername\fR (required)"
|
||||||
/* .IP "\fBuser\fR=\fIusername\fR:\fIgroupname\fR"
|
/* .IP "\fBuser\fR=\fIusername\fR:\fIgroupname\fR"
|
||||||
/* The external command is executed with the rights of the
|
/* Execute the external command with the rights of the
|
||||||
/* specified \fIusername\fR. The software refuses to execute
|
/* specified \fIusername\fR. The software refuses to execute
|
||||||
/* commands with root privileges, or with the privileges of the
|
/* commands with root privileges, or with the privileges of the
|
||||||
/* mail system owner. If \fIgroupname\fR is specified, the
|
/* mail system owner. If \fIgroupname\fR is specified, the
|
||||||
@@ -474,6 +485,7 @@ typedef struct {
|
|||||||
gid_t gid; /* command privileges */
|
gid_t gid; /* command privileges */
|
||||||
int flags; /* mail_copy() flags */
|
int flags; /* mail_copy() flags */
|
||||||
char *exec_dir; /* working directory */
|
char *exec_dir; /* working directory */
|
||||||
|
char *chroot_dir; /* chroot directory */
|
||||||
VSTRING *eol; /* output record delimiter */
|
VSTRING *eol; /* output record delimiter */
|
||||||
VSTRING *null_sender; /* null sender expansion */
|
VSTRING *null_sender; /* null sender expansion */
|
||||||
off_t size_limit; /* max size in bytes we will accept */
|
off_t size_limit; /* max size in bytes we will accept */
|
||||||
@@ -728,6 +740,7 @@ static void get_service_attr(PIPE_ATTR *attr, char **argv)
|
|||||||
attr->command = 0;
|
attr->command = 0;
|
||||||
attr->flags = 0;
|
attr->flags = 0;
|
||||||
attr->exec_dir = 0;
|
attr->exec_dir = 0;
|
||||||
|
attr->chroot_dir = 0;
|
||||||
attr->eol = vstring_strcpy(vstring_alloc(1), "\n");
|
attr->eol = vstring_strcpy(vstring_alloc(1), "\n");
|
||||||
attr->null_sender = vstring_strcpy(vstring_alloc(1), MAIL_ADDR_MAIL_DAEMON);
|
attr->null_sender = vstring_strcpy(vstring_alloc(1), MAIL_ADDR_MAIL_DAEMON);
|
||||||
attr->size_limit = 0;
|
attr->size_limit = 0;
|
||||||
@@ -807,6 +820,13 @@ static void get_service_attr(PIPE_ATTR *attr, char **argv)
|
|||||||
attr->exec_dir = mystrdup(*argv + sizeof("directory=") - 1);
|
attr->exec_dir = mystrdup(*argv + sizeof("directory=") - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* chroot=string
|
||||||
|
*/
|
||||||
|
else if (strncasecmp("chroot=", *argv, sizeof("chroot=") - 1) == 0) {
|
||||||
|
attr->chroot_dir = mystrdup(*argv + sizeof("chroot=") - 1);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* eol=string
|
* eol=string
|
||||||
*/
|
*/
|
||||||
@@ -1105,6 +1125,7 @@ static int deliver_message(DELIVER_REQUEST *request, char *service, char **argv)
|
|||||||
PIPE_CMD_EOL, STR(attr.eol),
|
PIPE_CMD_EOL, STR(attr.eol),
|
||||||
PIPE_CMD_EXPORT, export_env->argv,
|
PIPE_CMD_EXPORT, export_env->argv,
|
||||||
PIPE_CMD_CWD, attr.exec_dir,
|
PIPE_CMD_CWD, attr.exec_dir,
|
||||||
|
PIPE_CMD_CHROOT, attr.chroot_dir,
|
||||||
PIPE_CMD_ORIG_RCPT, rcpt_list->info[0].orig_addr,
|
PIPE_CMD_ORIG_RCPT, rcpt_list->info[0].orig_addr,
|
||||||
PIPE_CMD_DELIVERED, rcpt_list->info[0].address,
|
PIPE_CMD_DELIVERED, rcpt_list->info[0].address,
|
||||||
PIPE_CMD_END);
|
PIPE_CMD_END);
|
||||||
|
@@ -107,7 +107,9 @@ int myflock(int fd, int lock_style, int operation)
|
|||||||
-1, LOCK_SH | LOCK_NB, LOCK_EX | LOCK_NB, -1
|
-1, LOCK_SH | LOCK_NB, LOCK_EX | LOCK_NB, -1
|
||||||
};
|
};
|
||||||
|
|
||||||
status = flock(fd, lock_ops[operation]);
|
while ((status = flock(fd, lock_ops[operation])) < 0
|
||||||
|
&& errno == EINTR)
|
||||||
|
sleep(1);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -129,8 +131,7 @@ int myflock(int fd, int lock_style, int operation)
|
|||||||
lock.l_type = lock_ops[operation & ~MYFLOCK_OP_NOWAIT];
|
lock.l_type = lock_ops[operation & ~MYFLOCK_OP_NOWAIT];
|
||||||
request = (operation & MYFLOCK_OP_NOWAIT) ? F_SETLK : F_SETLKW;
|
request = (operation & MYFLOCK_OP_NOWAIT) ? F_SETLK : F_SETLKW;
|
||||||
while ((status = fcntl(fd, request, &lock)) < 0
|
while ((status = fcntl(fd, request, &lock)) < 0
|
||||||
&& request == F_SETLKW
|
&& errno == EINTR)
|
||||||
&& (errno == EINTR || errno == ENOLCK || errno == EDEADLK))
|
|
||||||
sleep(1);
|
sleep(1);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user