mirror of
https://github.com/vdukhovni/postfix
synced 2025-08-22 18:07:41 +00:00
postfix-3.11-20250717
This commit is contained in:
parent
9b4d4d966e
commit
13f0daa5f7
@ -29400,3 +29400,44 @@ Apologies for any names omitted.
|
|||||||
|
|
||||||
Uploaded the wrong postfix-3.11-20250713 tarball. Files:
|
Uploaded the wrong postfix-3.11-20250713 tarball. Files:
|
||||||
master/event_server.c, master/multi_server.c.
|
master/event_server.c, master/multi_server.c.
|
||||||
|
|
||||||
|
Deleted an <openssl/engine.h> dependency, because the feature is
|
||||||
|
being removed from OpenSSL, and Postfix no longer needs it. File:
|
||||||
|
posttls-finger/posttls-finger.c.
|
||||||
|
|
||||||
|
Updated the proxymap(8) manpage and some internal documentation.
|
||||||
|
File: proxymap/proxymap.c.
|
||||||
|
|
||||||
|
20250715
|
||||||
|
|
||||||
|
Cleanup: the proxymap 'open' service always returns the
|
||||||
|
dict->flags from a newly-initialized instance. This avoids
|
||||||
|
cross-talk between different clients. File: proxymap/proxymap.c.
|
||||||
|
|
||||||
|
20250716
|
||||||
|
|
||||||
|
Bugfix (defect introduced: Postfix 2.7, date 20121223):
|
||||||
|
segfault in the internal: table iterator when the table
|
||||||
|
contained exactly one element. File: util/htable.c.
|
||||||
|
|
||||||
|
Technical debt: allow an element to be deleted before the
|
||||||
|
internal: table's first/next iterator has visited it. File:
|
||||||
|
util/htable.c.
|
||||||
|
|
||||||
|
20250716
|
||||||
|
|
||||||
|
Bugfix (defect introduced: Postfix 2.8, date 20101230):
|
||||||
|
after detecting a cache table change and before starting a
|
||||||
|
new postscreen process, the old postscreen process did not
|
||||||
|
close the postscreen_cache_map, and therefore kept an
|
||||||
|
exclusive lock that could prevent a new postscreen process
|
||||||
|
from starting. Problem reported by Florian Piekert. File:
|
||||||
|
postscreen/postscreen.c.
|
||||||
|
|
||||||
|
20250717
|
||||||
|
|
||||||
|
Workaround: Postfix daemons no longer automatically restart
|
||||||
|
after a btree:, dbm:, hash:, lmdb:, or sdbm: table file
|
||||||
|
modification time change, when they opened that table for
|
||||||
|
writing. Files: util/dict.c, util/dict_db.c, util/dict_dbm.c,
|
||||||
|
util/dict_lmdb.c, util/dict_sdbm.c.
|
||||||
|
@ -222,7 +222,7 @@ POSTSCREEN(8) POSTSCREEN(8)
|
|||||||
text..." response, in an attempt to confuse bad SMTP clients so
|
text..." response, in an attempt to confuse bad SMTP clients so
|
||||||
that they speak before their turn (pre-greet).
|
that they speak before their turn (pre-greet).
|
||||||
|
|
||||||
<b><a href="postconf.5.html#postscreen_greet_wait">postscreen_greet_wait</a> (normal: 6s, overload: 2s)</b>
|
<b><a href="postconf.5.html#postscreen_greet_wait">postscreen_greet_wait</a> (normal: 6s, <a href="STRESS_README.html">overload</a>: 2s)</b>
|
||||||
The amount of time that <a href="postscreen.8.html"><b>postscreen</b>(8)</a> will wait for an SMTP
|
The amount of time that <a href="postscreen.8.html"><b>postscreen</b>(8)</a> will wait for an SMTP
|
||||||
client to send a command before its turn, and for DNS blocklist
|
client to send a command before its turn, and for DNS blocklist
|
||||||
lookup results to arrive (default: up to 2 seconds under stress,
|
lookup results to arrive (default: up to 2 seconds under stress,
|
||||||
@ -359,7 +359,7 @@ POSTSCREEN(8) POSTSCREEN(8)
|
|||||||
The limit on the total number of commands per SMTP session for
|
The limit on the total number of commands per SMTP session for
|
||||||
<a href="postscreen.8.html"><b>postscreen</b>(8)</a>'s built-in SMTP protocol engine.
|
<a href="postscreen.8.html"><b>postscreen</b>(8)</a>'s built-in SMTP protocol engine.
|
||||||
|
|
||||||
<b><a href="postconf.5.html#postscreen_command_time_limit">postscreen_command_time_limit</a> (normal: 300s, overload: 10s)</b>
|
<b><a href="postconf.5.html#postscreen_command_time_limit">postscreen_command_time_limit</a> (normal: 300s, <a href="STRESS_README.html">overload</a>: 10s)</b>
|
||||||
The time limit to read an entire command line with
|
The time limit to read an entire command line with
|
||||||
<a href="postscreen.8.html"><b>postscreen</b>(8)</a>'s built-in SMTP protocol engine.
|
<a href="postscreen.8.html"><b>postscreen</b>(8)</a>'s built-in SMTP protocol engine.
|
||||||
|
|
||||||
@ -405,7 +405,7 @@ POSTSCREEN(8) POSTSCREEN(8)
|
|||||||
|
|
||||||
<b><a href="postconf.5.html#delay_logging_resolution_limit">delay_logging_resolution_limit</a> (2)</b>
|
<b><a href="postconf.5.html#delay_logging_resolution_limit">delay_logging_resolution_limit</a> (2)</b>
|
||||||
The maximal number of digits after the decimal point when log-
|
The maximal number of digits after the decimal point when log-
|
||||||
ging sub-second delay values.
|
ging delay values.
|
||||||
|
|
||||||
<b><a href="postconf.5.html#command_directory">command_directory</a> (see 'postconf -d' output)</b>
|
<b><a href="postconf.5.html#command_directory">command_directory</a> (see 'postconf -d' output)</b>
|
||||||
The location of all postfix administrative commands.
|
The location of all postfix administrative commands.
|
||||||
@ -468,5 +468,8 @@ POSTSCREEN(8) POSTSCREEN(8)
|
|||||||
111 8th Avenue
|
111 8th Avenue
|
||||||
New York, NY 10011, USA
|
New York, NY 10011, USA
|
||||||
|
|
||||||
|
Wietse Venema
|
||||||
|
porcupine.org
|
||||||
|
|
||||||
POSTSCREEN(8)
|
POSTSCREEN(8)
|
||||||
</pre> </body> </html>
|
</pre> </body> </html>
|
||||||
|
@ -45,51 +45,60 @@ PROXYMAP(8) PROXYMAP(8)
|
|||||||
|
|
||||||
The <a href="proxymap.8.html"><b>proxymap</b>(8)</a> server implements the following requests:
|
The <a href="proxymap.8.html"><b>proxymap</b>(8)</a> server implements the following requests:
|
||||||
|
|
||||||
<b>open</b> <i>maptype:mapname flags</i>
|
<b>open</b> <i>maptype:mapname instance-flags</i>
|
||||||
Open the table with type <i>maptype</i> and name <i>mapname</i>, as controlled
|
Open the table with type <i>maptype</i> and name <i>mapname</i>, with initial
|
||||||
by <i>flags</i>. The reply includes the <i>maptype</i> dependent flags (to
|
dictionary flags <i>instance-flags</i>. The reply contains the actual
|
||||||
distinguish a fixed string table from a regular expression ta-
|
dictionary flags (for example, to distinguish a fixed-string ta-
|
||||||
ble).
|
ble from a regular-expression table).
|
||||||
|
|
||||||
<b>lookup</b> <i>maptype:mapname flags key</i>
|
<b>lookup</b> <i>maptype:mapname instance-flags request-flags key</i>
|
||||||
Look up the data stored under the requested key. The reply is
|
Look up the data stored under the requested key using the dic-
|
||||||
the request completion status code and the lookup result value.
|
tionary flags in <i>request-flags</i>. The reply contains the request
|
||||||
The <i>maptype:mapname</i> and <i>flags</i> are the same as with the <b>open</b>
|
completion status code, the resulting dictionary flags, and the
|
||||||
|
lookup result value. The <i>maptype:mapname</i> and <i>instance-flags</i> are
|
||||||
|
the same as with the <b>open</b> request.
|
||||||
|
|
||||||
|
<b>update</b> <i>maptype:mapname instance-flags request-flags key value</i>
|
||||||
|
Update the data stored under the requested key using the dictio-
|
||||||
|
nary flags in <i>request-flags</i>. The reply contains the request
|
||||||
|
completion status code and the resulting dictionary flags. The
|
||||||
|
<i>maptype:mapname</i> and <i>instance-flags</i> are the same as with the <b>open</b>
|
||||||
request.
|
request.
|
||||||
|
|
||||||
<b>update</b> <i>maptype:mapname flags key value</i>
|
|
||||||
Update the data stored under the requested key. The reply is
|
|
||||||
the request completion status code. The <i>maptype:mapname</i> and
|
|
||||||
<i>flags</i> are the same as with the <b>open</b> request.
|
|
||||||
|
|
||||||
To implement single-updater maps, specify a process limit of 1
|
To implement single-updater maps, specify a process limit of 1
|
||||||
in the <a href="master.5.html">master.cf</a> file entry for the <b>proxywrite</b> service.
|
in the <a href="master.5.html">master.cf</a> file entry for the <b>proxywrite</b> service.
|
||||||
|
|
||||||
This request is supported in Postfix 2.5 and later.
|
This request is supported in Postfix 2.5 and later.
|
||||||
|
|
||||||
<b>delete</b> <i>maptype:mapname flags key</i>
|
<b>delete</b> <i>maptype:mapname instance-flags request-flags key</i>
|
||||||
Delete the data stored under the requested key. The reply is
|
Delete the data stored under the requested key, using the dic-
|
||||||
the request completion status code. The <i>maptype:mapname</i> and
|
tionary flags in <i>request-flags</i>. The reply contains the request
|
||||||
<i>flags</i> are the same as with the <b>open</b> request.
|
completion status code and the resulting dictionary flags. The
|
||||||
|
<i>maptype:mapname</i> and <i>instance-flags</i> are the same as with the <b>open</b>
|
||||||
|
request.
|
||||||
|
|
||||||
This request is supported in Postfix 2.5 and later.
|
This request is supported in Postfix 2.5 and later.
|
||||||
|
|
||||||
<b>sequence</b> <i>maptype:mapname flags function</i>
|
<b>sequence</b> <i>maptype:mapname instance-flags request-flags function</i>
|
||||||
Iterate over the specified database. The <i>function</i> is one of
|
Iterate over the specified database, using the dictionary flags
|
||||||
DICT_SEQ_FUN_FIRST or DICT_SEQ_FUN_NEXT. The reply is the
|
in <i>request-flags</i>. The <i>function</i> is either DICT_SEQ_FUN_FIRST or
|
||||||
request completion status code and a lookup key and result
|
DICT_SEQ_FUN_NEXT. The reply contains the request completion
|
||||||
value, if found.
|
status code, the resulting dictionary flags, and a lookup key
|
||||||
|
and result value if found. The <i>maptype:mapname</i> and
|
||||||
|
<i>instance-flags</i> are the same as with the <b>open</b> request.
|
||||||
|
|
||||||
This request is supported in Postfix 2.9 and later.
|
This request is supported in Postfix 2.9 and later.
|
||||||
|
|
||||||
|
Not implemented: close
|
||||||
|
There is no <b>close</b> request, nor are tables implicitly closed when
|
||||||
|
a client disconnects. The purpose is to share tables among mul-
|
||||||
|
tiple client processes. Due to the absence of an explicit or
|
||||||
|
implicit <b>close</b>, updates are forced to be synchronous.
|
||||||
|
|
||||||
The request completion status is one of OK, RETRY, NOKEY (lookup failed
|
The request completion status is one of OK, RETRY, NOKEY (lookup failed
|
||||||
because the key was not found), BAD (malformed request) or DENY (the
|
because the key was not found), BAD (malformed request) or DENY (the
|
||||||
table is not approved for proxy read or update access).
|
table is not approved for proxy read or update access).
|
||||||
|
|
||||||
There is no <b>close</b> command, nor are tables implicitly closed when a
|
|
||||||
client disconnects. The purpose is to share tables among multiple
|
|
||||||
client processes.
|
|
||||||
|
|
||||||
<b><a name="server_process_management">SERVER PROCESS MANAGEMENT</a></b>
|
<b><a name="server_process_management">SERVER PROCESS MANAGEMENT</a></b>
|
||||||
<a href="proxymap.8.html"><b>proxymap</b>(8)</a> servers run under control by the Postfix <a href="master.8.html"><b>master</b>(8)</a> server.
|
<a href="proxymap.8.html"><b>proxymap</b>(8)</a> servers run under control by the Postfix <a href="master.8.html"><b>master</b>(8)</a> server.
|
||||||
Each server can handle multiple simultaneous connections. When all
|
Each server can handle multiple simultaneous connections. When all
|
||||||
@ -219,5 +228,8 @@ PROXYMAP(8) PROXYMAP(8)
|
|||||||
111 8th Avenue
|
111 8th Avenue
|
||||||
New York, NY 10011, USA
|
New York, NY 10011, USA
|
||||||
|
|
||||||
|
Wietse Venema
|
||||||
|
porcupine.org
|
||||||
|
|
||||||
PROXYMAP(8)
|
PROXYMAP(8)
|
||||||
</pre> </body> </html>
|
</pre> </body> </html>
|
||||||
|
@ -410,7 +410,7 @@ The default location of the Postfix main.cf and master.cf
|
|||||||
configuration files.
|
configuration files.
|
||||||
.IP "\fBdelay_logging_resolution_limit (2)\fR"
|
.IP "\fBdelay_logging_resolution_limit (2)\fR"
|
||||||
The maximal number of digits after the decimal point when logging
|
The maximal number of digits after the decimal point when logging
|
||||||
sub\-second delay values.
|
delay values.
|
||||||
.IP "\fBcommand_directory (see 'postconf -d' output)\fR"
|
.IP "\fBcommand_directory (see 'postconf -d' output)\fR"
|
||||||
The location of all postfix administrative commands.
|
The location of all postfix administrative commands.
|
||||||
.IP "\fBmax_idle (100s)\fR"
|
.IP "\fBmax_idle (100s)\fR"
|
||||||
@ -480,3 +480,6 @@ Wietse Venema
|
|||||||
Google, Inc.
|
Google, Inc.
|
||||||
111 8th Avenue
|
111 8th Avenue
|
||||||
New York, NY 10011, USA
|
New York, NY 10011, USA
|
||||||
|
|
||||||
|
Wietse Venema
|
||||||
|
porcupine.org
|
||||||
|
@ -46,21 +46,24 @@ that do not reliably support multiple writers (i.e. all
|
|||||||
file\-based tables that are not based on \fBlmdb\fR).
|
file\-based tables that are not based on \fBlmdb\fR).
|
||||||
.PP
|
.PP
|
||||||
The \fBproxymap\fR(8) server implements the following requests:
|
The \fBproxymap\fR(8) server implements the following requests:
|
||||||
.IP "\fBopen\fR \fImaptype:mapname flags\fR"
|
.IP "\fBopen\fR \fImaptype:mapname instance\-flags\fR"
|
||||||
Open the table with type \fImaptype\fR and name \fImapname\fR,
|
Open the table with type \fImaptype\fR and name \fImapname\fR,
|
||||||
as controlled by \fIflags\fR. The reply includes the \fImaptype\fR
|
with initial dictionary flags \fIinstance\-flags\fR. The reply
|
||||||
dependent flags (to distinguish a fixed string table from a regular
|
contains the actual dictionary flags (for example, to distinguish
|
||||||
expression table).
|
a fixed\-string table from a regular\-expression table).
|
||||||
.IP "\fBlookup\fR \fImaptype:mapname flags key\fR"
|
.IP "\fBlookup\fR \fImaptype:mapname instance\-flags request\-flags key\fR"
|
||||||
Look up the data stored under the requested key.
|
Look up the data stored under the requested key using the
|
||||||
The reply is the request completion status code and
|
dictionary flags in \fIrequest\-flags\fR.
|
||||||
the lookup result value.
|
The reply contains the request completion status code, the
|
||||||
The \fImaptype:mapname\fR and \fIflags\fR are the same
|
resulting dictionary flags, and the lookup result value.
|
||||||
|
The \fImaptype:mapname\fR and \fIinstance\-flags\fR are the same
|
||||||
as with the \fBopen\fR request.
|
as with the \fBopen\fR request.
|
||||||
.IP "\fBupdate\fR \fImaptype:mapname flags key value\fR"
|
.IP "\fBupdate\fR \fImaptype:mapname instance\-flags request\-flags key value\fR"
|
||||||
Update the data stored under the requested key.
|
Update the data stored under the requested key using the
|
||||||
The reply is the request completion status code.
|
dictionary flags in \fIrequest\-flags\fR.
|
||||||
The \fImaptype:mapname\fR and \fIflags\fR are the same
|
The reply contains the request completion status code and the
|
||||||
|
resulting dictionary flags.
|
||||||
|
The \fImaptype:mapname\fR and \fIinstance\-flags\fR are the same
|
||||||
as with the \fBopen\fR request.
|
as with the \fBopen\fR request.
|
||||||
.sp
|
.sp
|
||||||
To implement single\-updater maps, specify a process limit
|
To implement single\-updater maps, specify a process limit
|
||||||
@ -68,29 +71,36 @@ of 1 in the master.cf file entry for the \fBproxywrite\fR
|
|||||||
service.
|
service.
|
||||||
.sp
|
.sp
|
||||||
This request is supported in Postfix 2.5 and later.
|
This request is supported in Postfix 2.5 and later.
|
||||||
.IP "\fBdelete\fR \fImaptype:mapname flags key\fR"
|
.IP "\fBdelete\fR \fImaptype:mapname instance\-flags request\-flags key\fR"
|
||||||
Delete the data stored under the requested key.
|
Delete the data stored under the requested key, using the
|
||||||
The reply is the request completion status code.
|
dictionary flags in \fIrequest\-flags\fR.
|
||||||
The \fImaptype:mapname\fR and \fIflags\fR are the same
|
The reply contains the request completion status code and the
|
||||||
|
resulting dictionary flags.
|
||||||
|
The \fImaptype:mapname\fR and \fIinstance\-flags\fR are the same
|
||||||
as with the \fBopen\fR request.
|
as with the \fBopen\fR request.
|
||||||
.sp
|
.sp
|
||||||
This request is supported in Postfix 2.5 and later.
|
This request is supported in Postfix 2.5 and later.
|
||||||
.IP "\fBsequence\fR \fImaptype:mapname flags function\fR"
|
.IP "\fBsequence\fR \fImaptype:mapname instance\-flags request\-flags function\fR"
|
||||||
Iterate over the specified database. The \fIfunction\fR
|
Iterate over the specified database, using the dictionary flags
|
||||||
is one of DICT_SEQ_FUN_FIRST or DICT_SEQ_FUN_NEXT.
|
in \fIrequest\-flags\fR. The \fIfunction\fR is either
|
||||||
The reply is the request completion status code and
|
DICT_SEQ_FUN_FIRST or DICT_SEQ_FUN_NEXT.
|
||||||
a lookup key and result value, if found.
|
The reply contains the request completion status code, the
|
||||||
|
resulting dictionary flags, and a lookup key and result value
|
||||||
|
if found.
|
||||||
|
The \fImaptype:mapname\fR and \fIinstance\-flags\fR are the same
|
||||||
|
as with the \fBopen\fR request.
|
||||||
.sp
|
.sp
|
||||||
This request is supported in Postfix 2.9 and later.
|
This request is supported in Postfix 2.9 and later.
|
||||||
|
.IP "Not implemented: close"
|
||||||
|
There is no \fBclose\fR request, nor are tables implicitly closed
|
||||||
|
when a client disconnects. The purpose is to share tables among
|
||||||
|
multiple client processes. Due to the absence of an explicit or
|
||||||
|
implicit \fBclose\fR, updates are forced to be synchronous.
|
||||||
.PP
|
.PP
|
||||||
The request completion status is one of OK, RETRY, NOKEY
|
The request completion status is one of OK, RETRY, NOKEY
|
||||||
(lookup failed because the key was not found), BAD (malformed
|
(lookup failed because the key was not found), BAD (malformed
|
||||||
request) or DENY (the table is not approved for proxy read
|
request) or DENY (the table is not approved for proxy read
|
||||||
or update access).
|
or update access).
|
||||||
|
|
||||||
There is no \fBclose\fR command, nor are tables implicitly closed
|
|
||||||
when a client disconnects. The purpose is to share tables among
|
|
||||||
multiple client processes.
|
|
||||||
.SH "SERVER PROCESS MANAGEMENT"
|
.SH "SERVER PROCESS MANAGEMENT"
|
||||||
.na
|
.na
|
||||||
.nf
|
.nf
|
||||||
@ -241,3 +251,6 @@ Wietse Venema
|
|||||||
Google, Inc.
|
Google, Inc.
|
||||||
111 8th Avenue
|
111 8th Avenue
|
||||||
New York, NY 10011, USA
|
New York, NY 10011, USA
|
||||||
|
|
||||||
|
Wietse Venema
|
||||||
|
porcupine.org
|
||||||
|
@ -181,3 +181,5 @@ proto proto COMPATIBILITY_README html
|
|||||||
proxymap proxymap c
|
proxymap proxymap c
|
||||||
postmap postmap c postalias postalias c
|
postmap postmap c postalias postalias c
|
||||||
client Files dict h dict_proxy c proxymap proxymap c
|
client Files dict h dict_proxy c proxymap proxymap c
|
||||||
|
cross talk between different clients File proxymap proxymap c
|
||||||
|
postscreen postscreen c
|
||||||
|
@ -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 "20250714"
|
#define MAIL_RELEASE_DATE "20250717"
|
||||||
#define MAIL_VERSION_NUMBER "3.11"
|
#define MAIL_VERSION_NUMBER "3.11"
|
||||||
|
|
||||||
#ifdef SNAPSHOT
|
#ifdef SNAPSHOT
|
||||||
|
@ -370,7 +370,7 @@
|
|||||||
/* configuration files.
|
/* configuration files.
|
||||||
/* .IP "\fBdelay_logging_resolution_limit (2)\fR"
|
/* .IP "\fBdelay_logging_resolution_limit (2)\fR"
|
||||||
/* The maximal number of digits after the decimal point when logging
|
/* The maximal number of digits after the decimal point when logging
|
||||||
/* sub-second delay values.
|
/* delay values.
|
||||||
/* .IP "\fBcommand_directory (see 'postconf -d' output)\fR"
|
/* .IP "\fBcommand_directory (see 'postconf -d' output)\fR"
|
||||||
/* The location of all postfix administrative commands.
|
/* The location of all postfix administrative commands.
|
||||||
/* .IP "\fBmax_idle (100s)\fR"
|
/* .IP "\fBmax_idle (100s)\fR"
|
||||||
@ -430,6 +430,9 @@
|
|||||||
/* Google, Inc.
|
/* Google, Inc.
|
||||||
/* 111 8th Avenue
|
/* 111 8th Avenue
|
||||||
/* New York, NY 10011, USA
|
/* New York, NY 10011, USA
|
||||||
|
/*
|
||||||
|
/* Wietse Venema
|
||||||
|
/* porcupine.org
|
||||||
/*--*/
|
/*--*/
|
||||||
|
|
||||||
/* System library. */
|
/* System library. */
|
||||||
@ -996,7 +999,7 @@ static void pre_accept(char *unused_name, char **unused_argv)
|
|||||||
if (new_event_time >= last_event_time + 1
|
if (new_event_time >= last_event_time + 1
|
||||||
&& (name = dict_changed_name()) != 0) {
|
&& (name = dict_changed_name()) != 0) {
|
||||||
msg_info("table %s has changed - finishing in the background", name);
|
msg_info("table %s has changed - finishing in the background", name);
|
||||||
event_server_drain();
|
psc_drain(unused_name, unused_argv);
|
||||||
} else {
|
} else {
|
||||||
last_event_time = new_event_time;
|
last_event_time = new_event_time;
|
||||||
}
|
}
|
||||||
|
@ -414,7 +414,6 @@
|
|||||||
|
|
||||||
#ifdef USE_TLS
|
#ifdef USE_TLS
|
||||||
#include <tls_proxy.h>
|
#include <tls_proxy.h>
|
||||||
#include <openssl/engine.h>
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -40,21 +40,24 @@
|
|||||||
/* file-based tables that are not based on \fBlmdb\fR).
|
/* file-based tables that are not based on \fBlmdb\fR).
|
||||||
/* .PP
|
/* .PP
|
||||||
/* The \fBproxymap\fR(8) server implements the following requests:
|
/* The \fBproxymap\fR(8) server implements the following requests:
|
||||||
/* .IP "\fBopen\fR \fImaptype:mapname flags\fR"
|
/* .IP "\fBopen\fR \fImaptype:mapname instance-flags\fR"
|
||||||
/* Open the table with type \fImaptype\fR and name \fImapname\fR,
|
/* Open the table with type \fImaptype\fR and name \fImapname\fR,
|
||||||
/* as controlled by \fIflags\fR. The reply includes the \fImaptype\fR
|
/* with initial dictionary flags \fIinstance-flags\fR. The reply
|
||||||
/* dependent flags (to distinguish a fixed string table from a regular
|
/* contains the actual dictionary flags (for example, to distinguish
|
||||||
/* expression table).
|
/* a fixed-string table from a regular-expression table).
|
||||||
/* .IP "\fBlookup\fR \fImaptype:mapname flags key\fR"
|
/* .IP "\fBlookup\fR \fImaptype:mapname instance-flags request-flags key\fR"
|
||||||
/* Look up the data stored under the requested key.
|
/* Look up the data stored under the requested key using the
|
||||||
/* The reply is the request completion status code and
|
/* dictionary flags in \fIrequest-flags\fR.
|
||||||
/* the lookup result value.
|
/* The reply contains the request completion status code, the
|
||||||
/* The \fImaptype:mapname\fR and \fIflags\fR are the same
|
/* resulting dictionary flags, and the lookup result value.
|
||||||
|
/* The \fImaptype:mapname\fR and \fIinstance-flags\fR are the same
|
||||||
/* as with the \fBopen\fR request.
|
/* as with the \fBopen\fR request.
|
||||||
/* .IP "\fBupdate\fR \fImaptype:mapname flags key value\fR"
|
/* .IP "\fBupdate\fR \fImaptype:mapname instance-flags request-flags key value\fR"
|
||||||
/* Update the data stored under the requested key.
|
/* Update the data stored under the requested key using the
|
||||||
/* The reply is the request completion status code.
|
/* dictionary flags in \fIrequest-flags\fR.
|
||||||
/* The \fImaptype:mapname\fR and \fIflags\fR are the same
|
/* The reply contains the request completion status code and the
|
||||||
|
/* resulting dictionary flags.
|
||||||
|
/* The \fImaptype:mapname\fR and \fIinstance-flags\fR are the same
|
||||||
/* as with the \fBopen\fR request.
|
/* as with the \fBopen\fR request.
|
||||||
/* .sp
|
/* .sp
|
||||||
/* To implement single-updater maps, specify a process limit
|
/* To implement single-updater maps, specify a process limit
|
||||||
@ -62,29 +65,36 @@
|
|||||||
/* service.
|
/* service.
|
||||||
/* .sp
|
/* .sp
|
||||||
/* This request is supported in Postfix 2.5 and later.
|
/* This request is supported in Postfix 2.5 and later.
|
||||||
/* .IP "\fBdelete\fR \fImaptype:mapname flags key\fR"
|
/* .IP "\fBdelete\fR \fImaptype:mapname instance-flags request-flags key\fR"
|
||||||
/* Delete the data stored under the requested key.
|
/* Delete the data stored under the requested key, using the
|
||||||
/* The reply is the request completion status code.
|
/* dictionary flags in \fIrequest-flags\fR.
|
||||||
/* The \fImaptype:mapname\fR and \fIflags\fR are the same
|
/* The reply contains the request completion status code and the
|
||||||
|
/* resulting dictionary flags.
|
||||||
|
/* The \fImaptype:mapname\fR and \fIinstance-flags\fR are the same
|
||||||
/* as with the \fBopen\fR request.
|
/* as with the \fBopen\fR request.
|
||||||
/* .sp
|
/* .sp
|
||||||
/* This request is supported in Postfix 2.5 and later.
|
/* This request is supported in Postfix 2.5 and later.
|
||||||
/* .IP "\fBsequence\fR \fImaptype:mapname flags function\fR"
|
/* .IP "\fBsequence\fR \fImaptype:mapname instance-flags request-flags function\fR"
|
||||||
/* Iterate over the specified database. The \fIfunction\fR
|
/* Iterate over the specified database, using the dictionary flags
|
||||||
/* is one of DICT_SEQ_FUN_FIRST or DICT_SEQ_FUN_NEXT.
|
/* in \fIrequest-flags\fR. The \fIfunction\fR is either
|
||||||
/* The reply is the request completion status code and
|
/* DICT_SEQ_FUN_FIRST or DICT_SEQ_FUN_NEXT.
|
||||||
/* a lookup key and result value, if found.
|
/* The reply contains the request completion status code, the
|
||||||
|
/* resulting dictionary flags, and a lookup key and result value
|
||||||
|
/* if found.
|
||||||
|
/* The \fImaptype:mapname\fR and \fIinstance-flags\fR are the same
|
||||||
|
/* as with the \fBopen\fR request.
|
||||||
/* .sp
|
/* .sp
|
||||||
/* This request is supported in Postfix 2.9 and later.
|
/* This request is supported in Postfix 2.9 and later.
|
||||||
|
/* .IP "Not implemented: close"
|
||||||
|
/* There is no \fBclose\fR request, nor are tables implicitly closed
|
||||||
|
/* when a client disconnects. The purpose is to share tables among
|
||||||
|
/* multiple client processes. Due to the absence of an explicit or
|
||||||
|
/* implicit \fBclose\fR, updates are forced to be synchronous.
|
||||||
/* .PP
|
/* .PP
|
||||||
/* The request completion status is one of OK, RETRY, NOKEY
|
/* The request completion status is one of OK, RETRY, NOKEY
|
||||||
/* (lookup failed because the key was not found), BAD (malformed
|
/* (lookup failed because the key was not found), BAD (malformed
|
||||||
/* request) or DENY (the table is not approved for proxy read
|
/* request) or DENY (the table is not approved for proxy read
|
||||||
/* or update access).
|
/* or update access).
|
||||||
/*
|
|
||||||
/* There is no \fBclose\fR command, nor are tables implicitly closed
|
|
||||||
/* when a client disconnects. The purpose is to share tables among
|
|
||||||
/* multiple client processes.
|
|
||||||
/* SERVER PROCESS MANAGEMENT
|
/* SERVER PROCESS MANAGEMENT
|
||||||
/* .ad
|
/* .ad
|
||||||
/* .fi
|
/* .fi
|
||||||
@ -215,6 +225,9 @@
|
|||||||
/* Google, Inc.
|
/* Google, Inc.
|
||||||
/* 111 8th Avenue
|
/* 111 8th Avenue
|
||||||
/* New York, NY 10011, USA
|
/* New York, NY 10011, USA
|
||||||
|
/*
|
||||||
|
/* Wietse Venema
|
||||||
|
/* porcupine.org
|
||||||
/*--*/
|
/*--*/
|
||||||
|
|
||||||
/* System library. */
|
/* System library. */
|
||||||
@ -323,6 +336,8 @@ static char *get_nested_dict_name(char *type_name)
|
|||||||
static DICT *proxy_map_find(const char *map_type_name, int inst_flags,
|
static DICT *proxy_map_find(const char *map_type_name, int inst_flags,
|
||||||
int *statp)
|
int *statp)
|
||||||
{
|
{
|
||||||
|
static HTABLE *new_flags;
|
||||||
|
HTABLE_INFO *ht;
|
||||||
DICT *dict;
|
DICT *dict;
|
||||||
|
|
||||||
#define PROXY_COLON DICT_TYPE_PROXY ":"
|
#define PROXY_COLON DICT_TYPE_PROXY ":"
|
||||||
@ -360,6 +375,20 @@ static DICT *proxy_map_find(const char *map_type_name, int inst_flags,
|
|||||||
inst_flags);
|
inst_flags);
|
||||||
if (dict == 0)
|
if (dict == 0)
|
||||||
msg_panic("proxy_map_find: dict_open null result");
|
msg_panic("proxy_map_find: dict_open null result");
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Remember the mapping from dict->reg_name to the dict->flags of a
|
||||||
|
* newly-initialized instance. Always return an instance with those new
|
||||||
|
* dict->flags, to avoid crosstalk between different clients.
|
||||||
|
*/
|
||||||
|
if (new_flags == 0)
|
||||||
|
new_flags = htable_create(100);
|
||||||
|
if ((ht = htable_locate(new_flags, dict->reg_name)) == 0) {
|
||||||
|
(void) htable_enter(new_flags, dict->reg_name,
|
||||||
|
CAST_INT_TO_VOID_PTR(dict->flags));
|
||||||
|
} else {
|
||||||
|
dict->flags = CAST_ANY_PTR_TO_INT(ht->value);
|
||||||
|
}
|
||||||
dict->error = 0;
|
dict->error = 0;
|
||||||
return (dict);
|
return (dict);
|
||||||
}
|
}
|
||||||
|
@ -160,8 +160,8 @@
|
|||||||
/* .IP "char *context"
|
/* .IP "char *context"
|
||||||
/* Application context from the caller.
|
/* Application context from the caller.
|
||||||
/* .PP
|
/* .PP
|
||||||
/* dict_changed_name() returns non-zero when any dictionary needs to
|
/* dict_changed_name() returns non-zero when any dictionary is
|
||||||
/* be re-opened because it has changed or because it was unlinked.
|
/* opened read-only and has changed, or because it was unlinked.
|
||||||
/* A non-zero result is the name of a changed dictionary.
|
/* A non-zero result is the name of a changed dictionary.
|
||||||
/*
|
/*
|
||||||
/* dict_load_file_xt() reads name-value entries from the named file.
|
/* dict_load_file_xt() reads name-value entries from the named file.
|
||||||
@ -641,11 +641,12 @@ const char *dict_changed_name(void)
|
|||||||
dict = ((DICT_NODE *) h->value)->dict;
|
dict = ((DICT_NODE *) h->value)->dict;
|
||||||
if (dict->stat_fd < 0) /* not file-based */
|
if (dict->stat_fd < 0) /* not file-based */
|
||||||
continue;
|
continue;
|
||||||
if (dict->mtime == 0) /* not bloody likely */
|
if (dict->mtime < 0) /* not bloody likely */
|
||||||
msg_warn("%s: table %s: null time stamp", myname, h->key);
|
msg_warn("%s: table %s: negative time stamp", myname, h->key);
|
||||||
if (fstat(dict->stat_fd, &st) < 0)
|
if (fstat(dict->stat_fd, &st) < 0)
|
||||||
msg_fatal("%s: fstat: %m", myname);
|
msg_fatal("%s: fstat: %m", myname);
|
||||||
if (((dict->flags & DICT_FLAG_MULTI_WRITER) == 0
|
if (((dict->flags & DICT_FLAG_MULTI_WRITER) == 0
|
||||||
|
&& dict->mtime > 0
|
||||||
&& st.st_mtime != dict->mtime)
|
&& st.st_mtime != dict->mtime)
|
||||||
|| st.st_nlink == 0)
|
|| st.st_nlink == 0)
|
||||||
status = h->key;
|
status = h->key;
|
||||||
|
@ -789,6 +789,7 @@ static DICT *dict_db_open(const char *class, const char *path, int open_flags,
|
|||||||
dict_db->dict.stat_fd = dbfd;
|
dict_db->dict.stat_fd = dbfd;
|
||||||
if (fstat(dict_db->dict.stat_fd, &st) < 0)
|
if (fstat(dict_db->dict.stat_fd, &st) < 0)
|
||||||
msg_fatal("dict_db_open: fstat: %m");
|
msg_fatal("dict_db_open: fstat: %m");
|
||||||
|
if (open_flags == O_RDONLY)
|
||||||
dict_db->dict.mtime = st.st_mtime;
|
dict_db->dict.mtime = st.st_mtime;
|
||||||
dict_db->dict.owner.uid = st.st_uid;
|
dict_db->dict.owner.uid = st.st_uid;
|
||||||
dict_db->dict.owner.status = (st.st_uid != 0);
|
dict_db->dict.owner.status = (st.st_uid != 0);
|
||||||
|
@ -472,6 +472,7 @@ DICT *dict_dbm_open(const char *path, int open_flags, int dict_flags)
|
|||||||
msg_fatal("open database %s: cannot support GDBM", path);
|
msg_fatal("open database %s: cannot support GDBM", path);
|
||||||
if (fstat(dict_dbm->dict.stat_fd, &st) < 0)
|
if (fstat(dict_dbm->dict.stat_fd, &st) < 0)
|
||||||
msg_fatal("dict_dbm_open: fstat: %m");
|
msg_fatal("dict_dbm_open: fstat: %m");
|
||||||
|
if (open_mode == O_RDONLY)
|
||||||
dict_dbm->dict.mtime = st.st_mtime;
|
dict_dbm->dict.mtime = st.st_mtime;
|
||||||
dict_dbm->dict.owner.uid = st.st_uid;
|
dict_dbm->dict.owner.uid = st.st_uid;
|
||||||
dict_dbm->dict.owner.status = (st.st_uid != 0);
|
dict_dbm->dict.owner.status = (st.st_uid != 0);
|
||||||
|
@ -653,6 +653,7 @@ DICT *dict_lmdb_open(const char *path, int open_flags, int dict_flags)
|
|||||||
msg_fatal("dict_lmdb_open: fstat: %m");
|
msg_fatal("dict_lmdb_open: fstat: %m");
|
||||||
dict_lmdb->dict.lock_fd = dict_lmdb->dict.stat_fd = db_fd;
|
dict_lmdb->dict.lock_fd = dict_lmdb->dict.stat_fd = db_fd;
|
||||||
dict_lmdb->dict.lock_type = MYFLOCK_STYLE_FCNTL;
|
dict_lmdb->dict.lock_type = MYFLOCK_STYLE_FCNTL;
|
||||||
|
if (open_flags == O_RDONLY)
|
||||||
dict_lmdb->dict.mtime = st.st_mtime;
|
dict_lmdb->dict.mtime = st.st_mtime;
|
||||||
dict_lmdb->dict.owner.uid = st.st_uid;
|
dict_lmdb->dict.owner.uid = st.st_uid;
|
||||||
dict_lmdb->dict.owner.status = (st.st_uid != 0);
|
dict_lmdb->dict.owner.status = (st.st_uid != 0);
|
||||||
|
@ -449,6 +449,7 @@ DICT *dict_sdbm_open(const char *path, int open_flags, int dict_flags)
|
|||||||
dict_sdbm->dict.stat_fd = sdbm_pagfno(dbm);
|
dict_sdbm->dict.stat_fd = sdbm_pagfno(dbm);
|
||||||
if (fstat(dict_sdbm->dict.stat_fd, &st) < 0)
|
if (fstat(dict_sdbm->dict.stat_fd, &st) < 0)
|
||||||
msg_fatal("dict_sdbm_open: fstat: %m");
|
msg_fatal("dict_sdbm_open: fstat: %m");
|
||||||
|
if (open_flags == O_RDONLY)
|
||||||
dict_sdbm->dict.mtime = st.st_mtime;
|
dict_sdbm->dict.mtime = st.st_mtime;
|
||||||
dict_sdbm->dict.owner.uid = st.st_uid;
|
dict_sdbm->dict.owner.uid = st.st_uid;
|
||||||
dict_sdbm->dict.owner.status = (st.st_uid != 0);
|
dict_sdbm->dict.owner.status = (st.st_uid != 0);
|
||||||
|
@ -93,8 +93,7 @@
|
|||||||
/* htable_sequence() returns the first or next element depending
|
/* htable_sequence() returns the first or next element depending
|
||||||
/* on the value of the "how" argument. Specify HTABLE_SEQ_FIRST
|
/* on the value of the "how" argument. Specify HTABLE_SEQ_FIRST
|
||||||
/* to start a new sequence, HTABLE_SEQ_NEXT to continue, and
|
/* to start a new sequence, HTABLE_SEQ_NEXT to continue, and
|
||||||
/* HTABLE_SEQ_STOP to terminate a sequence early. The caller
|
/* HTABLE_SEQ_STOP to terminate a sequence early.
|
||||||
/* must not delete an element before it is visited.
|
|
||||||
/* RESTRICTIONS
|
/* RESTRICTIONS
|
||||||
/* A callback function should not modify the hash table that is
|
/* A callback function should not modify the hash table that is
|
||||||
/* specified to its caller.
|
/* specified to its caller.
|
||||||
@ -272,7 +271,7 @@ HTABLE_INFO *htable_locate(HTABLE *table, const char *key)
|
|||||||
void htable_delete(HTABLE *table, const char *key, void (*free_fn) (void *))
|
void htable_delete(HTABLE *table, const char *key, void (*free_fn) (void *))
|
||||||
{
|
{
|
||||||
if (table) {
|
if (table) {
|
||||||
HTABLE_INFO *ht;
|
HTABLE_INFO *ht, **sp;
|
||||||
HTABLE_INFO **h = table->data + htable_hash(key, table->size);
|
HTABLE_INFO **h = table->data + htable_hash(key, table->size);
|
||||||
|
|
||||||
#define STREQ(x,y) (x == y || (x[0] == y[0] && strcmp(x,y) == 0))
|
#define STREQ(x,y) (x == y || (x[0] == y[0] && strcmp(x,y) == 0))
|
||||||
@ -290,6 +289,14 @@ void htable_delete(HTABLE *table, const char *key, void (*free_fn) (void *))
|
|||||||
if (free_fn && ht->value)
|
if (free_fn && ht->value)
|
||||||
(*free_fn) (ht->value);
|
(*free_fn) (ht->value);
|
||||||
myfree((void *) ht);
|
myfree((void *) ht);
|
||||||
|
/* In case the first/next iterator has not yet visited it */
|
||||||
|
for (sp = table->seq_element; sp && *sp; sp++) {
|
||||||
|
if (*sp == ht) {
|
||||||
|
while ((*sp = sp[1]) != 0)
|
||||||
|
sp += 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -374,7 +381,7 @@ HTABLE_INFO *htable_sequence(HTABLE *table, int how)
|
|||||||
myfree((void *) table->seq_bucket);
|
myfree((void *) table->seq_bucket);
|
||||||
table->seq_bucket = htable_list(table);
|
table->seq_bucket = htable_list(table);
|
||||||
table->seq_element = table->seq_bucket;
|
table->seq_element = table->seq_bucket;
|
||||||
return (*(table->seq_element)++);
|
/* FALLTHROUGH */
|
||||||
case HTABLE_SEQ_NEXT: /* next element */
|
case HTABLE_SEQ_NEXT: /* next element */
|
||||||
if (table->seq_element && *table->seq_element)
|
if (table->seq_element && *table->seq_element)
|
||||||
return (*(table->seq_element)++);
|
return (*(table->seq_element)++);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user