mirror of
https://github.com/vdukhovni/postfix
synced 2025-08-22 09:57:34 +00:00
postfix-3.10-20250109
This commit is contained in:
parent
a98bc4ee9b
commit
085f0e5f31
@ -28780,3 +28780,18 @@ Apologies for any names omitted.
|
||||
|
||||
Cleanup: the netstring client sets or clears errno to improve
|
||||
error messages from its callers. File: util/netstring.c.
|
||||
|
||||
20250109
|
||||
|
||||
Bugfix (defect introduced: Postfix 2.6): fixed the parsing
|
||||
of multiple commas in a multi_instance_directories parameter
|
||||
value. Michael Tokarev. Files: conf/postfix-script,
|
||||
conf/post-install, conf/postfix-wrapper, proto/postfix-wrapper.
|
||||
|
||||
Cleanup: replace static result buffer with per-instance buffer.
|
||||
Michael Tokarev. File: util/dict_cdb.c.
|
||||
|
||||
Feature: first/next iterator support for cdb: tables, if
|
||||
built with tinycdb. Michael Tokarev. Wietse added a test
|
||||
and documentation. Files: util/dict_cdb.c proto/CDB_README.html,
|
||||
postmap/Makefile.in.
|
||||
|
@ -17,8 +17,25 @@ temporarily while a CDB file is under construction). CDB databases are
|
||||
maintained with the postmap(1) or postalias(1) command. The DATABASE_README
|
||||
document has general information about Postfix databases.
|
||||
|
||||
CDB support is available with Postfix 2.2 and later releases. This document
|
||||
describes how to build Postfix with CDB support.
|
||||
You can use "cdb:" tables wherever you can use read-only "hash", "btree" or
|
||||
"lmdb" tables with the following limitations:
|
||||
|
||||
* CDB databases cannot be larger than 4GB on LP64 and ILP32 systems, because
|
||||
the CDB library API uses unsigned integers for file offsets.
|
||||
|
||||
* The "ppoossttmmaapp --ii" (incremental record insertion) and "ppoossttmmaapp --dd"
|
||||
(incremental record deletion) command-line options are not available. For
|
||||
the same reason the "cdb:" map type cannot be used to for persistent
|
||||
caches, such as the address verification cache for the verify(8) service,
|
||||
the TLS session cache for the tlsmgr(8) service, or the dynamic allowlist
|
||||
for postscreen(8).
|
||||
|
||||
* The "sequence" operation ("ppoossttmmaapp --ss" or "ppoossttaalliiaass --ss") is available only
|
||||
wen Postfix is built with tinycdb by Michael Tokarev, not with the original
|
||||
cdb library by Daniel Bernstein.
|
||||
|
||||
CDB support is available with Postfix 2.2 and later releases. The remainder of
|
||||
this document describes how to build Postfix with CDB support.
|
||||
|
||||
BBuuiillddiinngg PPoossttffiixx wwiitthh CCDDBB ssuuppppoorrtt
|
||||
|
||||
@ -64,11 +81,3 @@ building a dynamically-loaded or statically-loaded CDB database client.
|
||||
database library dependencies. And that was exactly what dynamic database
|
||||
client loading was meant to avoid.
|
||||
|
||||
After Postfix has been built with cdb support, you can use "cdb" tables
|
||||
wherever you can use read-only "hash", "btree" or "dbm" tables. However, the
|
||||
"ppoossttmmaapp --ii" (incremental record insertion) and "ppoossttmmaapp --dd" (incremental
|
||||
record deletion) command-line options are not available. For the same reason
|
||||
the "cdb" map type cannot be used to store the persistent address verification
|
||||
cache for the verify(8) service, or to store TLS session information for the
|
||||
tlsmgr(8) service.
|
||||
|
||||
|
@ -19,6 +19,9 @@ Wish list:
|
||||
relay_recipient_maps empty should default to 'no valid
|
||||
recipients'. Subject to compatibility level.
|
||||
|
||||
Replace static result buffers with per-instance buffers in
|
||||
dict_unix.c, dict_ni*c.
|
||||
|
||||
The Milter 'quarantine' action should be reported with a
|
||||
call-back function, instead of setting the Milter default
|
||||
reply. However, we still need the existing 'reply' based
|
||||
|
@ -296,7 +296,7 @@ test -d "$config_directory" || {
|
||||
|
||||
instances=`test ! -f $def_config_directory/main.cf ||
|
||||
$POSTCONF -qc $def_config_directory -h multi_instance_directories |
|
||||
sed 's/,/ /'` || exit 1
|
||||
sed 'y/,/ /'` || exit 1
|
||||
|
||||
update_shared_files=1
|
||||
for name in $instances
|
||||
|
@ -97,7 +97,7 @@ def_config_directory=`$command_directory/postconf -dh config_directory` || {
|
||||
|
||||
instances=`test ! -f $def_config_directory/main.cf ||
|
||||
$command_directory/postconf -qc $def_config_directory \
|
||||
-h multi_instance_directories | sed 's/,/ /'` || {
|
||||
-h multi_instance_directories | sed 'y/,/ /'` || {
|
||||
$FATAL cannot execute $command_directory/postconf!
|
||||
exit 1
|
||||
}
|
||||
|
@ -188,7 +188,7 @@ POSTFIX=$command_directory/postfix
|
||||
# Canonicalize the instance directory list. The list is specified
|
||||
# in startup order.
|
||||
|
||||
instance_dirs=`$POSTCONF -h multi_instance_directories | sed 's/,/ /'` ||
|
||||
instance_dirs=`$POSTCONF -h multi_instance_directories | sed 'y/,/ /'` ||
|
||||
exit 1
|
||||
|
||||
case "$1" in
|
||||
|
@ -35,8 +35,33 @@ under construction). CDB databases are maintained with the <a href="postmap.1.h
|
||||
or <a href="postalias.1.html">postalias(1)</a> command. The <a href="DATABASE_README.html">DATABASE_README</a> document has general
|
||||
information about Postfix databases. </p>
|
||||
|
||||
<p> You can use "<a href="CDB_README.html">cdb</a>:" tables wherever you can use read-only "hash",
|
||||
"btree" or "lmdb" tables with the following limitations: </p>
|
||||
|
||||
<ul>
|
||||
|
||||
<li> <p> CDB databases cannot be larger than 4GB on LP64 and ILP32
|
||||
systems, because the CDB library API uses unsigned integers for
|
||||
file offsets. </p>
|
||||
|
||||
<li> <p> The "<b>postmap -i</b>" (incremental record insertion) and
|
||||
"<b>postmap -d</b>" (incremental record deletion) command-line
|
||||
options are not available. For the same reason the "<a href="CDB_README.html">cdb</a>:" map type
|
||||
cannot be used to for persistent caches, such as the address
|
||||
verification cache for the <a href="verify.8.html">verify(8)</a> service, the TLS session cache
|
||||
for the <a href="tlsmgr.8.html">tlsmgr(8)</a> service, or the dynamic allowlist for <a href="postscreen.8.html">postscreen(8)</a>.
|
||||
</p>
|
||||
|
||||
<li> <p> The "sequence" operation ("<b>postmap -s</b>" or "<b>postalias
|
||||
-s</b>") is available only wen Postfix is built with tinycdb by
|
||||
Michael Tokarev, not with the original cdb library by Daniel Bernstein.
|
||||
</p>
|
||||
|
||||
</ul>
|
||||
|
||||
<p> CDB support is available with Postfix 2.2 and later releases.
|
||||
This document describes how to build Postfix with CDB support. </p>
|
||||
The remainder of this document describes how to build Postfix with
|
||||
CDB support. </p>
|
||||
|
||||
<h2>Building Postfix with CDB support</h2>
|
||||
|
||||
@ -99,12 +124,3 @@ will have CDB database library dependencies. And that was exactly
|
||||
what dynamic database client loading was meant to avoid. </p>
|
||||
|
||||
</blockquote>
|
||||
|
||||
<p> After Postfix has been built with cdb support, you can use
|
||||
"cdb" tables wherever you can use read-only "hash", "btree" or
|
||||
"dbm" tables. However, the "<b>postmap -i</b>" (incremental record
|
||||
insertion) and "<b>postmap -d</b>" (incremental record deletion)
|
||||
command-line options are not available. For the same reason the
|
||||
"cdb" map type cannot be used to store the persistent address
|
||||
verification cache for the <a href="verify.8.html">verify(8)</a> service, or to store
|
||||
TLS session information for the <a href="tlsmgr.8.html">tlsmgr(8)</a> service. </p>
|
||||
|
@ -106,7 +106,7 @@ POSTFIX-WRAPPER(5) POSTFIX-WRAPPER(5)
|
||||
POSTCONF=$<a href="postconf.5.html#command_directory">command_directory</a>/postconf
|
||||
POSTFIX=$<a href="postconf.5.html#command_directory">command_directory</a>/postfix
|
||||
instance_dirs=`$POSTCONF -h <a href="postconf.5.html#multi_instance_directories">multi_instance_directories</a> |
|
||||
sed 's/,/ /'` || exit 1
|
||||
sed 'y/,/ /'` || exit 1
|
||||
|
||||
err=0
|
||||
for dir in $<a href="postconf.5.html#config_directory">config_directory</a> $instance_dirs
|
||||
|
@ -123,7 +123,7 @@ manager implementation:
|
||||
POSTCONF=$command_directory/postconf
|
||||
POSTFIX=$command_directory/postfix
|
||||
instance_dirs=\`$POSTCONF \-h multi_instance_directories |
|
||||
sed 's/,/ /'\` || exit 1
|
||||
sed 'y/,/ /'\` || exit 1
|
||||
|
||||
err=0
|
||||
for dir in $config_directory $instance_dirs
|
||||
|
@ -35,8 +35,33 @@ under construction). CDB databases are maintained with the postmap(1)
|
||||
or postalias(1) command. The DATABASE_README document has general
|
||||
information about Postfix databases. </p>
|
||||
|
||||
<p> You can use "cdb:" tables wherever you can use read-only "hash",
|
||||
"btree" or "lmdb" tables with the following limitations: </p>
|
||||
|
||||
<ul>
|
||||
|
||||
<li> <p> CDB databases cannot be larger than 4GB on LP64 and ILP32
|
||||
systems, because the CDB library API uses unsigned integers for
|
||||
file offsets. </p>
|
||||
|
||||
<li> <p> The "<b>postmap -i</b>" (incremental record insertion) and
|
||||
"<b>postmap -d</b>" (incremental record deletion) command-line
|
||||
options are not available. For the same reason the "cdb:" map type
|
||||
cannot be used to for persistent caches, such as the address
|
||||
verification cache for the verify(8) service, the TLS session cache
|
||||
for the tlsmgr(8) service, or the dynamic allowlist for postscreen(8).
|
||||
</p>
|
||||
|
||||
<li> <p> The "sequence" operation ("<b>postmap -s</b>" or "<b>postalias
|
||||
-s</b>") is available only wen Postfix is built with tinycdb by
|
||||
Michael Tokarev, not with the original cdb library by Daniel Bernstein.
|
||||
</p>
|
||||
|
||||
</ul>
|
||||
|
||||
<p> CDB support is available with Postfix 2.2 and later releases.
|
||||
This document describes how to build Postfix with CDB support. </p>
|
||||
The remainder of this document describes how to build Postfix with
|
||||
CDB support. </p>
|
||||
|
||||
<h2>Building Postfix with CDB support</h2>
|
||||
|
||||
@ -99,12 +124,3 @@ will have CDB database library dependencies. And that was exactly
|
||||
what dynamic database client loading was meant to avoid. </p>
|
||||
|
||||
</blockquote>
|
||||
|
||||
<p> After Postfix has been built with cdb support, you can use
|
||||
"cdb" tables wherever you can use read-only "hash", "btree" or
|
||||
"dbm" tables. However, the "<b>postmap -i</b>" (incremental record
|
||||
insertion) and "<b>postmap -d</b>" (incremental record deletion)
|
||||
command-line options are not available. For the same reason the
|
||||
"cdb" map type cannot be used to store the persistent address
|
||||
verification cache for the verify(8) service, or to store
|
||||
TLS session information for the tlsmgr(8) service. </p>
|
||||
|
@ -113,7 +113,7 @@
|
||||
# POSTCONF=$command_directory/postconf
|
||||
# POSTFIX=$command_directory/postfix
|
||||
# instance_dirs=\`$POSTCONF -h multi_instance_directories |
|
||||
# sed 's/,/ /'\` || exit 1
|
||||
# sed 'y/,/ /'\` || exit 1
|
||||
#
|
||||
# err=0
|
||||
# for dir in $config_directory $instance_dirs
|
||||
|
@ -1659,3 +1659,4 @@ GECOS
|
||||
iso
|
||||
ORCPT
|
||||
RET
|
||||
ILP
|
||||
|
@ -1854,3 +1854,5 @@ Charset
|
||||
atext
|
||||
qp
|
||||
cntrl
|
||||
TINYCDB
|
||||
getdata
|
||||
|
@ -20,7 +20,7 @@
|
||||
* Patches change both the patchlevel and the release date. Snapshots have no
|
||||
* patchlevel; they change the release date only.
|
||||
*/
|
||||
#define MAIL_RELEASE_DATE "20250107"
|
||||
#define MAIL_RELEASE_DATE "20250109"
|
||||
#define MAIL_VERSION_NUMBER "3.10"
|
||||
|
||||
#ifdef SNAPSHOT
|
||||
|
@ -27,7 +27,7 @@ update: ../../bin/$(PROG)
|
||||
cp $(PROG) ../../bin
|
||||
|
||||
tests: test1 test2 fail_test quote_test file_test lmdb_abb_test \
|
||||
lmdb_bulk_test lmdb_incr_test
|
||||
lmdb_bulk_test lmdb_incr_test cdb_bulk_test
|
||||
|
||||
root_tests:
|
||||
|
||||
@ -74,6 +74,17 @@ file_test: $(PROG) file_test.in file_test.ref
|
||||
diff file_test.ref file_test.tmp
|
||||
rm -f file_test.tmp file_test_map.* postmap-file-1 postmap-file-2
|
||||
|
||||
cdb_bulk_test: $(PROG)
|
||||
rm -f cdb_bulk.cdb main.cf
|
||||
tr A-Z a-z < /usr/share/dict/words| \
|
||||
sed -e 's/.*/& &/' -e 10000q| LANG=C sort -u >cdb_bulk
|
||||
touch -t 197101010000 main.cf
|
||||
($(SHLIB_ENV) $(VALGRIND) ./postmap -c . cdb:cdb_bulk; \
|
||||
$(SHLIB_ENV) $(VALGRIND) ./postmap -s cdb:cdb_bulk | \
|
||||
LANG=C sort > cdb_bulk.tmp)
|
||||
cmp cdb_bulk cdb_bulk.tmp
|
||||
rm -f cdb_bulk cdb_bulk.tmp cdb_bulk.cdb main.cf
|
||||
|
||||
lmdb_abb_test: $(PROG) lmdb_abb lmdb_abb.ref
|
||||
rm -f lmdb_abb.lmdb
|
||||
($(SHLIB_ENV) $(VALGRIND) ./postmap lmdb:lmdb_abb; \
|
||||
@ -86,6 +97,7 @@ lmdb_bulk_test: $(PROG)
|
||||
tr A-Z a-z < /usr/share/dict/words| \
|
||||
sed -e 's/.*/& &/' -e 10000q| LANG=C sort -u >lmdb_retry
|
||||
echo lmdb_map_size=10240 >main.cf
|
||||
touch -t 197101010000 main.cf
|
||||
($(SHLIB_ENV) $(VALGRIND) ./postmap -c . lmdb:lmdb_retry; \
|
||||
$(SHLIB_ENV) $(VALGRIND) ./postmap -s lmdb:lmdb_retry | \
|
||||
LANG=C sort > lmdb_retry.tmp)
|
||||
@ -97,6 +109,7 @@ lmdb_incr_test: $(PROG)
|
||||
tr A-Z a-z < /usr/share/dict/words| \
|
||||
sed -e 's/.*/& &/' -e 1000q| LANG=C sort -u >lmdb_retry
|
||||
echo lmdb_map_size=10240 >main.cf
|
||||
touch -t 197101010000 main.cf
|
||||
($(SHLIB_ENV) $(VALGRIND) ./postmap -ic . lmdb:lmdb_retry <lmdb_retry; \
|
||||
$(SHLIB_ENV) $(VALGRIND) ./postmap -s lmdb:lmdb_retry | \
|
||||
LANG=C sort > lmdb_retry.tmp)
|
||||
|
@ -84,6 +84,11 @@
|
||||
typedef struct {
|
||||
DICT dict; /* generic members */
|
||||
struct cdb cdb; /* cdb structure */
|
||||
VSTRING *val_buf; /* value result */
|
||||
#ifdef TINYCDB_VERSION
|
||||
VSTRING *key_buf; /* key result */
|
||||
unsigned seq_cptr; /* current sequence pointer */
|
||||
#endif
|
||||
} DICT_CDBQ; /* query interface */
|
||||
|
||||
typedef struct {
|
||||
@ -93,15 +98,31 @@ typedef struct {
|
||||
char *tmp_path; /* temporary pathname (.tmp) */
|
||||
} DICT_CDBM; /* rebuild interface */
|
||||
|
||||
/* dict_cdbq_getdata - get data out of the cdb using given buffer */
|
||||
|
||||
static const char *dict_cdbq_get_data(DICT_CDBQ *dict_cdbq,
|
||||
VSTRING **bufp, unsigned len, unsigned pos)
|
||||
{
|
||||
VSTRING *buf = *bufp;
|
||||
|
||||
if (!buf)
|
||||
buf = *bufp = vstring_alloc(len < 20 ? 20 : len);
|
||||
VSTRING_RESET(buf);
|
||||
VSTRING_SPACE(buf, len);
|
||||
|
||||
if (cdb_read(&dict_cdbq->cdb, vstring_str(buf), len, pos) < 0)
|
||||
msg_fatal("error reading %s: %m", dict_cdbq->dict.name);
|
||||
vstring_set_payload_size(buf, len);
|
||||
VSTRING_TERMINATE(buf);
|
||||
return vstring_str(buf);
|
||||
}
|
||||
|
||||
/* dict_cdbq_lookup - find database entry, query mode */
|
||||
|
||||
static const char *dict_cdbq_lookup(DICT *dict, const char *name)
|
||||
{
|
||||
DICT_CDBQ *dict_cdbq = (DICT_CDBQ *) dict;
|
||||
unsigned vlen;
|
||||
int status = 0;
|
||||
static char *buf;
|
||||
static unsigned len;
|
||||
const char *result = 0;
|
||||
|
||||
dict->error = 0;
|
||||
@ -141,25 +162,56 @@ static const char *dict_cdbq_lookup(DICT *dict, const char *name)
|
||||
msg_fatal("error reading %s: %m", dict->name);
|
||||
|
||||
if (status) {
|
||||
vlen = cdb_datalen(&dict_cdbq->cdb);
|
||||
if (len < vlen) {
|
||||
if (buf == 0)
|
||||
buf = mymalloc(vlen + 1);
|
||||
else
|
||||
buf = myrealloc(buf, vlen + 1);
|
||||
len = vlen;
|
||||
}
|
||||
if (cdb_read(&dict_cdbq->cdb, buf, vlen,
|
||||
cdb_datapos(&dict_cdbq->cdb)) < 0)
|
||||
msg_fatal("error reading %s: %m", dict->name);
|
||||
buf[vlen] = '\0';
|
||||
result = buf;
|
||||
result = dict_cdbq_get_data(dict_cdbq, &dict_cdbq->val_buf,
|
||||
cdb_datalen(&dict_cdbq->cdb), cdb_datapos(&dict_cdbq->cdb));
|
||||
}
|
||||
/* No locking so not release the lock. */
|
||||
|
||||
return (result);
|
||||
}
|
||||
|
||||
#ifdef TINYCDB_VERSION
|
||||
|
||||
/* dict_cdbq_sequence - traverse the dictionary */
|
||||
|
||||
static int dict_cdbq_sequence(DICT *dict, int function,
|
||||
const char **key, const char **value)
|
||||
{
|
||||
const char *myname = "dict_cdbq_sequence";
|
||||
DICT_CDBQ *dict_cdbq = (DICT_CDBQ *) dict;
|
||||
int status;
|
||||
|
||||
switch (function) {
|
||||
case DICT_SEQ_FUN_FIRST:
|
||||
cdb_seqinit(&dict_cdbq->seq_cptr, &dict_cdbq->cdb);
|
||||
break;
|
||||
case DICT_SEQ_FUN_NEXT:
|
||||
if (!dict_cdbq->seq_cptr)
|
||||
msg_panic("%s: %s: no cursor", myname, dict_cdbq->dict.name);
|
||||
break;
|
||||
default:
|
||||
msg_panic("%s: invalid function %d", myname, function);
|
||||
}
|
||||
|
||||
status = cdb_seqnext(&dict_cdbq->seq_cptr, &dict_cdbq->cdb);
|
||||
|
||||
if (status < 0)
|
||||
msg_fatal("error seeking %s: %m", dict_cdbq->dict.name);
|
||||
|
||||
if (!status) {
|
||||
dict_cdbq->seq_cptr = 0;
|
||||
return -1; /* not found */
|
||||
}
|
||||
*key = dict_cdbq_get_data(dict_cdbq, &dict_cdbq->key_buf,
|
||||
cdb_keylen(&dict_cdbq->cdb), cdb_keypos(&dict_cdbq->cdb));
|
||||
*value = dict_cdbq_get_data(dict_cdbq, &dict_cdbq->val_buf,
|
||||
cdb_datalen(&dict_cdbq->cdb), cdb_datapos(&dict_cdbq->cdb));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* TINYCDB_VERSION */
|
||||
|
||||
/* dict_cdbq_close - close data base, query mode */
|
||||
|
||||
static void dict_cdbq_close(DICT *dict)
|
||||
@ -170,6 +222,12 @@ static void dict_cdbq_close(DICT *dict)
|
||||
close(dict->stat_fd);
|
||||
if (dict->fold_buf)
|
||||
vstring_free(dict->fold_buf);
|
||||
if (dict_cdbq->val_buf)
|
||||
vstring_free(dict_cdbq->val_buf);
|
||||
#ifdef TINYCDB_VERSION
|
||||
if (dict_cdbq->key_buf)
|
||||
vstring_free(dict_cdbq->key_buf);
|
||||
#endif
|
||||
dict_free(dict);
|
||||
}
|
||||
|
||||
@ -200,9 +258,13 @@ static DICT *dict_cdbq_open(const char *path, int dict_flags)
|
||||
|
||||
dict_cdbq = (DICT_CDBQ *) dict_alloc(DICT_TYPE_CDB,
|
||||
cdb_path, sizeof(*dict_cdbq));
|
||||
dict_cdbq->val_buf = 0;
|
||||
#if defined(TINYCDB_VERSION)
|
||||
dict_cdbq->key_buf = 0;
|
||||
dict_cdbq->seq_cptr = 0;
|
||||
if (cdb_init(&(dict_cdbq->cdb), fd) != 0)
|
||||
msg_fatal("dict_cdbq_open: unable to init %s: %m", cdb_path);
|
||||
dict_cdbq->dict.sequence = dict_cdbq_sequence;
|
||||
#else
|
||||
cdb_init(&(dict_cdbq->cdb), fd);
|
||||
#endif
|
||||
|
Loading…
x
Reference in New Issue
Block a user