2
0
mirror of https://github.com/vdukhovni/postfix synced 2025-08-29 13:18:12 +00:00

postfix-1.1.8-20020508

This commit is contained in:
Wietse Venema 2002-05-08 00:00:00 -05:00 committed by Viktor Dukhovni
parent 8cae9ae6db
commit 54594e6d23
47 changed files with 259 additions and 194 deletions

View File

@ -6344,6 +6344,29 @@ Apologies for any names omitted.
Berkeley DB create and read buffer size controls. Files:
util/dict_db.[hc], global/mail_params.[hc], global/mkmap_db.c.
20020507
Cleanup: simplified the hash/btree cache management code.
The caches are now per table instead of shared, and the
default read cache size is reduced to 128 kBytes. File:
util/dict_db.c.
20020508
Bugfix: close an obscure source routing relaying loophole
involving postfix-style virtual domains. Problem reported
by Victor Duchovny. File: smtpd/smtpd_check.c.
Bugfix: mail_addr_map() used the "wrong" @ character in
addresses with multiple @. Victor Duchovny. File:
global/mail_addr_map.c.
Bugfix: for address localpart quoting, now quote @ as a
special character everywhere, except when resolving addresses.
Previously, the @ was nowhere quoted as a special character,
not even in SMTP commands. Files: global/quote_82[12]_local.c
and clients.
Open problems:
Low: sendmail does not store null command-line recipients.

View File

@ -95,13 +95,18 @@ Tweaking performance
Postfix provides two configuration parameters that control how much
buffering memory Berkeley DB will use.
- berkeley_db_create_buffer_size (default: 16 MBytes). This setting
is used by the postalias and postmap commands. For "hash" files
performance degrades rapidly unless the memory pool is O(file size).
For "btree" files peformance is good with sorted input even for
small memory pools, but with random input degrades rapidly unless
the memory pool is O(file size).
- berkeley_db_create_buffer_size (default: 16 MBytes per table).
This setting is used by the postalias and postmap commands. For
"hash" files, create performance degrades rapidly unless the memory
pool is O(file size). For "btree" files, create peformance is good
with sorted input even for small memory pools, but with random
input degrades rapidly unless the memory pool is O(file size).
- berkeley_db_read_buffer_size (default: 256 kBytes). This setting
is used by all other Postfix programs. The buffer size is adequate
for reading.
- berkeley_db_read_buffer_size (default: 128 kBytes per table).
This setting is used by all other Postfix programs. The buffer size
is adequate for reading. If the cache is smaller than the table,
random read performance is hardly cache size dependent, except with
btree tables, where the cache size must be large enough to contain
the entire path from the root node. Empirical evidence shows that
64 kBytes may be sufficient. We double the size to play safe, and
to anticipate changes in implementation and bloat.

View File

@ -137,22 +137,24 @@ We will set up a content filtering program that receives SMTP mail
via localhost port 10025, and that submits SMTP mail back into
Postfix via localhost port 10026.
..................................
: Postfix :
----->smtpd \ /local---->
: -cleanup->queue- :
---->pickup / ^ | \smtp----->
: | v :
: smtpd smtp :
: 10026 | :
......................|...........
^ |
| v
....|............
: | 10025 :
: filter :
: :
.................
...................................
: Postfix :
----->smtpd \ :
: -cleanup-\ /local---->
---->pickup / -queue- :
: cleanup2/ | \smtp----->
: ^ v :
: | v :
: smtpd smtp :
: 10026 | :
.......................|...........
^ |
| v
....|.............
: | 10025 :
: filter :
: :
..................
To enable content filtering in this manner, specify in main.cf a
new parameter:
@ -214,16 +216,31 @@ a dedicated listener on port localhost 10026:
-o content_filter=
-o local_recipient_maps=
-o myhostname=localhost.domain.name
-o disable_dns_lookups=yes
-o cleanup_service=cleanup2
cleanup2 unix n - n - 0 cleanup
-o header_checks=
-o body_checks=
This is just another SMTP server. It is configured NOT to request
content filtering for incoming mail. The server has the same process
limit as the filter master.cf entry.
This is just another SMTP server. The "-o content_filter=" requests
no content filtering for incoming mail. The server has the same
process limit as the "filter" master.cf entry.
The "-o local_recipient_maps=" is a safety in case you have specified
local_recipient_maps in the main.cf file. That setting could
interfere with content filtering.
local_recipient_maps in the main.cf file. That could interfere with
content filtering.
The SMTP server is configured to use a different hostname in the
greeting message (this is necessary for testing when I simply use
no filtering program and let the SMTP content filtering interfaces
talk directly to each other).
The "-o myhostname=localhost.domain.name" avoids a possible problem
if the content filter is picky about the hostname that Postfix
sends in SMTP server replies.
The "-o disable_dns_lookups=yes" turns off unnecessary DNS lookups
that would only slow things down.
The "-o cleanup_service=cleanup2" specifies that mail received via
the secondary SMTP server should be send into the cleanup2 service.
As the master.cf entry above shows, the cleanup2 service is like
the normal cleanup server, but with some features turned off: no
processing of header patterns, and no processing of body message
patterns. This can save you some precious CPU cycles.

View File

@ -19,6 +19,19 @@ always_bcc =
#
daemon_timeout = 18000s
# The berkeley_db_create_buffer_size parameter specifies the per-table
# I/O buffer size for programs that create Berkeley DB hash or btree
# tables. Specify a byte count. The default buffer size is 16 MBytes.
#
berkeley_db_create_buffer_size = 16777216
# The berkeley_db_read_buffer_size parameter specifies the per-table
# I/O buffer size for programs that read Berkeley DB hash or btree
# tables. Specify a byte count. The default buffer size is 128
# kBytes.
#
berkeley_db_read_buffer_size = 131072
# The default_database_type parameter specifies the default database
# type to use in postalias(1) and postmap(1) commands. On many UNIX
# systems the default type is either `dbm' or `hash'. The default is

View File

@ -83,6 +83,7 @@ bounce_append_service.o: ../../include/vstream.h
bounce_append_service.o: ../../include/stringops.h
bounce_append_service.o: ../../include/mail_queue.h
bounce_append_service.o: ../../include/quote_822_local.h
bounce_append_service.o: ../../include/quote_flags.h
bounce_append_service.o: ../../include/deliver_flock.h
bounce_append_service.o: ../../include/myflock.h
bounce_append_service.o: bounce_service.h
@ -123,6 +124,7 @@ bounce_notify_util.o: ../../include/vstream.h
bounce_notify_util.o: ../../include/line_wrap.h
bounce_notify_util.o: ../../include/mail_queue.h
bounce_notify_util.o: ../../include/quote_822_local.h
bounce_notify_util.o: ../../include/quote_flags.h
bounce_notify_util.o: ../../include/mail_params.h
bounce_notify_util.o: ../../include/is_header.h
bounce_notify_util.o: ../../include/record.h

View File

@ -103,7 +103,8 @@ int bounce_append_service(char *service, char *queue_id,
if (*recipient)
vstream_fprintf(log, "<%s>: ",
printable(vstring_str(quote_822_local(in_buf, recipient)), '?'));
printable(vstring_str(quote_822_local(in_buf, recipient,
QUOTE_FLAG_8BITCLEAN)), '?'));
else
vstream_fprintf(log, "<>: ");
vstream_fputs(printable(why, '?'), log);

View File

@ -288,7 +288,8 @@ int bounce_header(VSTREAM *bounce, BOUNCE_INFO *bounce_info,
"Subject: Delayed Mail (still being retried)");
}
post_mail_fprintf(bounce, "To: %s",
STR(quote_822_local(bounce_info->buf, dest)));
STR(quote_822_local(bounce_info->buf, dest,
QUOTE_FLAG_8BITCLEAN)));
/*
* MIME header.

View File

@ -184,6 +184,7 @@ cleanup_map11.o: ../../include/cleanup_user.h
cleanup_map11.o: ../../include/mail_addr_map.h
cleanup_map11.o: ../../include/maps.h
cleanup_map11.o: ../../include/quote_822_local.h
cleanup_map11.o: ../../include/quote_flags.h
cleanup_map11.o: cleanup.h
cleanup_map11.o: ../../include/tok822.h
cleanup_map11.o: ../../include/resolve_clnt.h
@ -203,6 +204,7 @@ cleanup_map1n.o: ../../include/mail_addr_map.h
cleanup_map1n.o: ../../include/maps.h
cleanup_map1n.o: ../../include/cleanup_user.h
cleanup_map1n.o: ../../include/quote_822_local.h
cleanup_map1n.o: ../../include/quote_flags.h
cleanup_map1n.o: ../../include/been_here.h
cleanup_map1n.o: cleanup.h
cleanup_map1n.o: ../../include/tok822.h
@ -222,6 +224,7 @@ cleanup_masquerade.o: ../../include/mail_params.h
cleanup_masquerade.o: ../../include/tok822.h
cleanup_masquerade.o: ../../include/resolve_clnt.h
cleanup_masquerade.o: ../../include/quote_822_local.h
cleanup_masquerade.o: ../../include/quote_flags.h
cleanup_masquerade.o: cleanup.h
cleanup_masquerade.o: ../../include/vstream.h
cleanup_masquerade.o: ../../include/maps.h
@ -245,6 +248,7 @@ cleanup_message.o: ../../include/tok822.h
cleanup_message.o: ../../include/resolve_clnt.h
cleanup_message.o: ../../include/header_opts.h
cleanup_message.o: ../../include/quote_822_local.h
cleanup_message.o: ../../include/quote_flags.h
cleanup_message.o: ../../include/mail_params.h
cleanup_message.o: ../../include/mail_date.h
cleanup_message.o: ../../include/mail_addr.h
@ -301,6 +305,7 @@ cleanup_rewrite.o: ../../include/tok822.h
cleanup_rewrite.o: ../../include/resolve_clnt.h
cleanup_rewrite.o: ../../include/rewrite_clnt.h
cleanup_rewrite.o: ../../include/quote_822_local.h
cleanup_rewrite.o: ../../include/quote_flags.h
cleanup_rewrite.o: cleanup.h
cleanup_rewrite.o: ../../include/vstream.h
cleanup_rewrite.o: ../../include/argv.h

View File

@ -231,6 +231,13 @@ static void cleanup_service(VSTREAM *src, char *unused_service, char **argv)
/* void */ ;
}
/*
* Log something to make timeout errors easier to debug.
*/
if (vstream_ftimeout(src))
msg_warn("%s: read timeout on %s",
state->queue_id, VSTREAM_PATH(src));
/*
* Finish this message, and report the result status to the client.
*/

View File

@ -162,7 +162,7 @@ void cleanup_map11_internal(CLEANUP_STATE *state, VSTRING *addr,
* checking in one place, instead of having error handling code all over
* the place.
*/
quote_822_local(temp, STR(addr));
quote_822_local(temp, STR(addr), QUOTE_FLAG_8BITCLEAN);
cleanup_map11_external(state, temp, maps, propagate);
unquote_822_local(addr, STR(temp));
vstring_free(temp);

View File

@ -112,7 +112,8 @@ ARGV *cleanup_map1n_internal(CLEANUP_STATE *state, char *addr,
state->queue_id, maps->title, addr);
break;
}
quote_822_local(state->temp1, argv->argv[arg]);
quote_822_local(state->temp1, argv->argv[arg],
QUOTE_FLAG_8BITCLEAN);
if ((lookup = mail_addr_map(maps, STR(state->temp1), propagate)) != 0) {
saved_lhs = mystrdup(argv->argv[arg]);
for (i = 0; i < lookup->argc; i++) {

View File

@ -165,7 +165,7 @@ void cleanup_masquerade_internal(VSTRING *addr, ARGV *masq_domains)
{
VSTRING *temp = vstring_alloc(100);
quote_822_local(temp, STR(addr));
quote_822_local(temp, STR(addr), QUOTE_FLAG_8BITCLEAN);
cleanup_masquerade_external(temp, masq_domains);
unquote_822_local(addr, STR(temp));

View File

@ -194,6 +194,7 @@ static void cleanup_rewrite_sender(CLEANUP_STATE *state, HEADER_OPTS *hdr_opts)
cleanup_extract_internal(state->header_buf, *tpp);
}
vstring_sprintf(state->header_buf, "%s: ", hdr_opts->name);
/* XXX should quote_822_local the address local parts. */
tok822_externalize(state->header_buf, tree, TOK822_STR_HEAD);
myfree((char *) addr_list);
tok822_free_tree(tree);
@ -247,6 +248,7 @@ static void cleanup_rewrite_recip(CLEANUP_STATE *state, HEADER_OPTS *hdr_opts)
cleanup_masquerade_tree(*tpp, cleanup_masq_domains);
}
vstring_sprintf(state->header_buf, "%s: ", hdr_opts->name);
/* XXX should quote_822_local the address local parts. */
tok822_externalize(state->header_buf, tree, TOK822_STR_HEAD);
myfree((char *) addr_list);
tok822_free_tree(tree);
@ -430,7 +432,8 @@ static void cleanup_missing_headers(CLEANUP_STATE *state)
if ((state->headers_seen & (1 << (state->resent[0] ?
HDR_RESENT_FROM : HDR_FROM))) == 0) {
quote_822_local(state->temp1, *state->sender ?
state->sender : MAIL_ADDR_MAIL_DAEMON);
state->sender : MAIL_ADDR_MAIL_DAEMON,
QUOTE_FLAG_8BITCLEAN);
vstring_sprintf(state->temp2, "%sFrom: %s",
state->resent, vstring_str(state->temp1));
if (*state->sender && state->fullname && *state->fullname) {

View File

@ -95,7 +95,7 @@ void cleanup_rewrite_internal(VSTRING *result, const char *addr)
VSTRING *dst = vstring_alloc(100);
VSTRING *src = vstring_alloc(100);
quote_822_local(src, addr);
quote_822_local(src, addr, QUOTE_FLAG_8BITCLEAN);
cleanup_rewrite_external(dst, STR(src));
unquote_822_local(result, STR(dst));
vstring_free(dst);

View File

@ -57,7 +57,7 @@ HDRS = been_here.h bounce.h canon_addr.h cleanup_user.h clnt_stream.h \
rewrite_clnt.h sent.h smtp_stream.h split_addr.h string_list.h \
sys_exits.h timed_ipc.h tok822.h xtext.h bounce_log.h flush_clnt.h \
mbox_conf.h mbox_open.h abounce.h qmqp_proto.h verp_sender.h \
match_parent_style.h
match_parent_style.h quote_flags.h
TESTSRC = rec2stream.c stream2rec.c recdump.c
WARN = -W -Wformat -Wimplicit -Wmissing-prototypes \
-Wparentheses -Wstrict-prototypes -Wswitch -Wuninitialized \
@ -581,6 +581,7 @@ mail_copy.o: ../../include/vstring.h
mail_copy.o: ../../include/vstring_vstream.h
mail_copy.o: ../../include/stringops.h
mail_copy.o: quote_822_local.h
mail_copy.o: quote_flags.h
mail_copy.o: record.h
mail_copy.o: rec_type.h
mail_copy.o: mail_queue.h
@ -625,11 +626,14 @@ mail_params.o: ../../include/stringops.h
mail_params.o: ../../include/vstring.h
mail_params.o: ../../include/vbuf.h
mail_params.o: ../../include/safe.h
mail_params.o: ../../include/dict_db.h
mail_params.o: ../../include/dict.h
mail_params.o: ../../include/vstream.h
mail_params.o: ../../include/argv.h
mail_params.o: mynetworks.h
mail_params.o: mail_conf.h
mail_params.o: mail_version.h
mail_params.o: mail_proto.h
mail_params.o: ../../include/vstream.h
mail_params.o: ../../include/iostuff.h
mail_params.o: ../../include/attr.h
mail_params.o: verp_sender.h
@ -773,6 +777,7 @@ mkmap_db.o: ../../include/dict.h
mkmap_db.o: ../../include/vstream.h
mkmap_db.o: ../../include/argv.h
mkmap_db.o: ../../include/dict_db.h
mkmap_db.o: mail_params.h
mkmap_db.o: mkmap.h
mkmap_dbm.o: mkmap_dbm.c
mkmap_dbm.o: ../../include/sys_defs.h
@ -887,11 +892,13 @@ quote_821_local.o: ../../include/sys_defs.h
quote_821_local.o: ../../include/vstring.h
quote_821_local.o: ../../include/vbuf.h
quote_821_local.o: quote_821_local.h
quote_821_local.o: quote_flags.h
quote_822_local.o: quote_822_local.c
quote_822_local.o: ../../include/sys_defs.h
quote_822_local.o: ../../include/vstring.h
quote_822_local.o: ../../include/vbuf.h
quote_822_local.o: quote_822_local.h
quote_822_local.o: quote_flags.h
rec2stream.o: rec2stream.c
rec2stream.o: ../../include/sys_defs.h
rec2stream.o: ../../include/vstring.h
@ -971,6 +978,7 @@ rewrite_clnt.o: ../../include/vstring_vstream.h
rewrite_clnt.o: ../../include/events.h
rewrite_clnt.o: ../../include/iostuff.h
rewrite_clnt.o: quote_822_local.h
rewrite_clnt.o: quote_flags.h
rewrite_clnt.o: mail_proto.h
rewrite_clnt.o: ../../include/attr.h
rewrite_clnt.o: mail_params.h

View File

@ -94,7 +94,7 @@ ARGV *mail_addr_map(MAPS *path, const char *address, int propagate)
*/
if (*string == '@') {
buffer = vstring_alloc(100);
if ((ratsign = strchr(address, '@')) != 0)
if ((ratsign = strrchr(address, '@')) != 0)
vstring_strncpy(buffer, address, ratsign - address);
else
vstring_strcpy(buffer, address);

View File

@ -144,7 +144,7 @@ int mail_copy(const char *sender, const char *delivered,
if (flags & (MAIL_COPY_FROM | MAIL_COPY_RETURN_PATH)) {
if (sender == 0)
msg_panic("%s: null sender", myname);
quote_822_local(buf, sender);
quote_822_local(buf, sender, QUOTE_FLAG_8BITCLEAN);
if (flags & MAIL_COPY_FROM) {
time(&now);
vstream_fprintf(dst, "From %s %.24s%s", *sender == 0 ?
@ -159,7 +159,7 @@ int mail_copy(const char *sender, const char *delivered,
if (flags & MAIL_COPY_DELIVERED) {
if (delivered == 0)
msg_panic("%s: null delivered", myname);
quote_822_local(buf, delivered);
quote_822_local(buf, delivered, QUOTE_FLAG_8BITCLEAN);
vstream_fprintf(dst, "Delivered-To: %s%s",
lowercase(vstring_str(buf)), eol);
}

View File

@ -525,7 +525,7 @@ void mail_params_init()
check_sgid_group();
check_overlap();
#ifdef HAS_DB
dict_db_mpool_size = var_db_read_buf;
dict_db_cache_size = var_db_read_buf;
#endif
/*

View File

@ -1483,7 +1483,7 @@ extern char *var_mdr_defer_errs;
extern int var_db_create_buf;
#define VAR_DB_READ_BUF "berkeley_db_read_buffer_size"
#define DEF_DB_READ_BUF (256 *1024)
#define DEF_DB_READ_BUF (128 *1024)
extern int var_db_read_buf;
/* LICENSE

View File

@ -20,7 +20,7 @@
* Patches change the patchlevel and the release date. Snapshots change the
* release date only, unless they include the same bugfix as a patch release.
*/
#define MAIL_RELEASE_DATE "20020505"
#define MAIL_RELEASE_DATE "20020508"
#define VAR_MAIL_VERSION "mail_version"
#define DEF_MAIL_VERSION "1.1.8-" MAIL_RELEASE_DATE

View File

@ -68,13 +68,14 @@ static MKMAP *mkmap_db_open(const char *path,
MKMAP *mkmap = (MKMAP *) mymalloc(sizeof(*mkmap));
/*
* Override the default mpool size for map (re)builds.
* Override the default per-table cache size for map (re)builds.
*
* db_mpool_size" is defined in util/dict_db.c and defaults to 256K, which
* db_cache_size" is defined in util/dict_db.c and defaults to 128kB, which
* works well for the lookup code.
*
* We use a larger memory pool when building ".db" files. For "hash" files
* performance degrades rapidly unless the memory pool is O(file size).
* We use a larger per-table cache when building ".db" files. For "hash"
* files performance degrades rapidly unless the memory pool is O(file
* size).
*
* For "btree" files peformance is good with sorted input even for small
* memory pools, but with random input degrades rapidly unless the memory
@ -84,7 +85,7 @@ static MKMAP *mkmap_db_open(const char *path,
* size becomes an object property, instead of being specified by poking
* a global variable so that it becomes a class property.
*/
dict_db_mpool_size = var_db_create_buf;
dict_db_cache_size = var_db_create_buf;
/*
* Fill in the generic members.

View File

@ -6,9 +6,10 @@
/* SYNOPSIS
/* #include "quote_821_local.h"
/*
/* VSTRING *quote_821_local(dst, src)
/* VSTRING *quote_821_local(dst, src, flags)
/* VSTRING *dst;
/* char *src;
/* int flags;
/* DESCRIPTION
/* quote_821_local() quotes the local part of a mailbox address and
/* returns a result that can be used in SMTP commands as specified
@ -19,6 +20,14 @@
/* The result.
/* .IP src
/* The input address.
/* .IP flags
/* Bit-wise OR of zero or more of the following.
/* .RS
/* .IP QUOTE_FLAG_8BITCLEAN
/* In violation with RFCs, treat 8-bit text as ordinary text.
/* .IP QUOTE_FLAG_EXPOSE_AT
/* In violation with RFCs, treat `@' as an ordinary character.
/* .RE
/* STANDARDS
/* RFC 821 (SMTP protocol)
/* BUGS
@ -55,7 +64,7 @@
/* is_821_dot_string - is this local-part an rfc 821 dot-string? */
static int is_821_dot_string(char *local_part, char *end)
static int is_821_dot_string(char *local_part, char *end, int flags)
{
char *cp;
int ch;
@ -70,7 +79,7 @@ static int is_821_dot_string(char *local_part, char *end)
for (cp = local_part; cp < end && (ch = *(unsigned char *) cp) != 0; cp++) {
if (ch == '.' && cp[1] == '.')
return (NO);
if (ch > 127)
if (ch > 127 && !(flags & QUOTE_FLAG_8BITCLEAN))
return (NO);
if (ch == ' ')
return (NO);
@ -81,7 +90,7 @@ static int is_821_dot_string(char *local_part, char *end)
|| ch == '[' || ch == ']'
|| ch == '\\' || ch == ','
|| ch == ';' || ch == ':'
/* || ch == '@' */ || ch == '"')
|| (ch == '@' && !(flags & QUOTE_FLAG_EXPOSE_AT)) || ch == '"')
return (NO);
}
if (cp[-1] == '.')
@ -114,7 +123,7 @@ static VSTRING *make_821_quoted_string(VSTRING *dst, char *local_part, char *end
/* quote_821_local - quote local part of address according to rfc 821 */
VSTRING *quote_821_local(VSTRING *dst, char *addr)
VSTRING *quote_821_local(VSTRING *dst, char *addr, int flags)
{
char *at;
@ -125,7 +134,7 @@ VSTRING *quote_821_local(VSTRING *dst, char *addr)
*/
if ((at = strrchr(addr, '@')) == 0) /* just in case */
at = addr + strlen(addr); /* should not happen */
if (is_821_dot_string(addr, at)) {
if (is_821_dot_string(addr, at, flags)) {
return (vstring_strcpy(dst, addr));
} else {
make_821_quoted_string(dst, addr, at);

View File

@ -13,10 +13,15 @@
*/
#include <vstring.h>
/*
* Global library.
*/
#include <quote_flags.h>
/*
* External interface.
*/
extern VSTRING *quote_821_local(VSTRING *, char *);
extern VSTRING *quote_821_local(VSTRING *, char *, int);
/* LICENSE
/* .ad

View File

@ -6,9 +6,10 @@
/* SYNOPSIS
/* #include <quote_822_local.h>
/*
/* VSTRING *quote_822_local(dst, src)
/* VSTRING *quote_822_local(dst, src, flags)
/* VSTRING *dst;
/* const char *src;
/* int flags;
/*
/* VSTRING *unquote_822_local(dst, src)
/* VSTRING *dst;
@ -27,6 +28,14 @@
/* The result.
/* .IP src
/* The input address.
/* .IP flags
/* Bit-wise OR of zero or more of the following.
/* .RS
/* .IP QUOTE_FLAG_8BITCLEAN
/* In violation with RFCs, treat 8-bit text as ordinary text.
/* .IP QUOTE_FLAG_EXPOSE_AT
/* In violation with RFCs, treat `@' as an ordinary character.
/* .RE
/* STANDARDS
/* RFC 822 (ARPA Internet Text Messages)
/* BUGS
@ -65,7 +74,7 @@
/* is_822_dot_string - is this local-part an rfc 822 dot-string? */
static int is_822_dot_string(const char *local_part, const char *end)
static int is_822_dot_string(const char *local_part, const char *end, int flags)
{
const char *cp;
int ch;
@ -83,17 +92,15 @@ static int is_822_dot_string(const char *local_part, const char *end)
for (cp = local_part; cp < end && (ch = *(unsigned char *) cp) != 0; cp++) {
if (ch == '.' && (cp + 1) < end && cp[1] == '.')
return (NO);
#if 0
if (ch > 127)
if (ch > 127 && !(flags & QUOTE_FLAG_8BITCLEAN))
return (NO);
#endif
if (ch == ' ')
return (NO);
if (ISCNTRL(ch))
return (NO);
if (ch == '(' || ch == ')'
|| ch == '<' || ch == '>'
/* || ch == '@' */ || ch == ','
|| (ch == '@' && !(flags & QUOTE_FLAG_EXPOSE_AT)) || ch == ','
|| ch == ';' || ch == ':'
|| ch == '\\' || ch == '"'
|| ch == '[' || ch == ']')
@ -107,7 +114,7 @@ static int is_822_dot_string(const char *local_part, const char *end)
/* make_822_quoted_string - make quoted-string from local-part */
static VSTRING *make_822_quoted_string(VSTRING *dst, const char *local_part,
const char *end)
const char *end)
{
const char *cp;
int ch;
@ -128,7 +135,7 @@ static VSTRING *make_822_quoted_string(VSTRING *dst, const char *local_part,
/* quote_822_local - quote local part of mailbox according to rfc 822 */
VSTRING *quote_822_local(VSTRING *dst, const char *mbox)
VSTRING *quote_822_local(VSTRING *dst, const char *mbox, int flags)
{
const char *start; /* first byte of localpart */
const char *end; /* first byte after localpart */
@ -146,7 +153,7 @@ VSTRING *quote_822_local(VSTRING *dst, const char *mbox)
start = mbox;
if ((end = strrchr(start, '@')) == 0)
end = start + strlen(start);
if (is_822_dot_string(start, end)) {
if (is_822_dot_string(start, end, flags)) {
return (vstring_strcpy(dst, mbox));
} else {
vstring_strncpy(dst, mbox, start - mbox);

View File

@ -16,10 +16,15 @@
*/
#include <vstring.h>
/*
* Global library.
*/
#include <quote_flags.h>
/*
* External interface.
*/
extern VSTRING *quote_822_local(VSTRING *, const char *);
extern VSTRING *quote_822_local(VSTRING *, const char *, int);
extern VSTRING *unquote_822_local(VSTRING *, const char *);
/* LICENSE

View File

@ -0,0 +1,26 @@
/*++
/* NAME
/* quote_flags 3h
/* SUMMARY
/* quote rfc 821/822 local part
/* SYNOPSIS
/* #include "quote_flags.h"
/* DESCRIPTION
/* .nf
/*
* External interface.
*/
#define QUOTE_FLAG_8BITCLEAN (1<<0) /* be 8-bit clean */
#define QUOTE_FLAG_EXPOSE_AT (1<<1) /* @ is ordinary text */
/* LICENSE
/* .ad
/* .fi
/* The Secure Mailer license must be distributed with this software.
/* AUTHOR(S)
/* Wietse Venema
/* IBM T.J. Watson Research
/* P.O. Box 704
/* Yorktown Heights, NY 10598, USA
/*--*/

View File

@ -166,7 +166,7 @@ VSTRING *rewrite_clnt_internal(const char *ruleset, const char *addr, VSTRING *r
* Convert the address from internal address form to external RFC822
* form, then rewrite it. After rewriting, convert to internal form.
*/
quote_822_local(src, addr);
quote_822_local(src, addr, QUOTE_FLAG_8BITCLEAN);
rewrite_clnt(ruleset, STR(src), dst);
unquote_822_local(result, STR(dst));
vstring_free(src);

View File

@ -162,6 +162,7 @@ lmtp_proto.o: ../../include/rec_type.h
lmtp_proto.o: ../../include/off_cvt.h
lmtp_proto.o: ../../include/mark_corrupt.h
lmtp_proto.o: ../../include/quote_821_local.h
lmtp_proto.o: ../../include/quote_flags.h
lmtp_proto.o: lmtp.h
lmtp_proto.o: ../../include/argv.h
lmtp_proto.o: lmtp_sasl.h

View File

@ -296,7 +296,7 @@ static int lmtp_loop(LMTP_STATE *state, int send_state, int recv_state)
*/
#define REWRITE_ADDRESS(addr) do { \
if (*(addr)) { \
quote_821_local(state->scratch, addr); \
quote_821_local(state->scratch, addr, QUOTE_FLAG_8BITCLEAN); \
myfree(addr); \
addr = mystrdup(vstring_str(state->scratch)); \
lowercase(addr); \

View File

@ -139,6 +139,7 @@ delivered.o: ../../include/record.h
delivered.o: ../../include/rec_type.h
delivered.o: ../../include/is_header.h
delivered.o: ../../include/quote_822_local.h
delivered.o: ../../include/quote_flags.h
delivered.o: ../../include/header_opts.h
delivered.o: local.h
delivered.o: ../../include/been_here.h

View File

@ -137,7 +137,7 @@ int delivered_find(HTABLE *table, char *address)
* header. We must therefore apply the same transformation when looking
* up the recipient. Lowercase the delivered-to address for consistency.
*/
quote_822_local(buf, address);
quote_822_local(buf, address, QUOTE_FLAG_8BITCLEAN);
lowercase(STR(buf));
ht = htable_locate(table, STR(buf));
return (ht != 0);

View File

@ -83,4 +83,5 @@ pipe.o: ../../include/canon_addr.h
pipe.o: ../../include/split_addr.h
pipe.o: ../../include/off_cvt.h
pipe.o: ../../include/quote_822_local.h
pipe.o: ../../include/quote_flags.h
pipe.o: ../../include/mail_server.h

View File

@ -382,7 +382,7 @@ static void morph_recipient(VSTRING *buf, const char *address, int flags)
* Quote the recipient address as appropriate.
*/
if (flags & PIPE_OPT_QUOTE_LOCAL)
quote_822_local(buf, address);
quote_822_local(buf, address, QUOTE_FLAG_8BITCLEAN);
else
vstring_strcpy(buf, address);
@ -826,7 +826,7 @@ static int deliver_message(DELIVER_REQUEST *request, char *service, char **argv)
buf = vstring_alloc(10);
if (attr.flags & PIPE_OPT_QUOTE_LOCAL) {
quote_822_local(buf, request->sender);
quote_822_local(buf, request->sender, QUOTE_FLAG_8BITCLEAN);
dict_update(PIPE_DICT_TABLE, PIPE_DICT_SENDER, STR(buf));
} else
dict_update(PIPE_DICT_TABLE, PIPE_DICT_SENDER, request->sender);

View File

@ -92,6 +92,7 @@ postalias.o: ../../include/stringops.h
postalias.o: ../../include/split_at.h
postalias.o: ../../include/get_hostname.h
postalias.o: ../../include/vstring_vstream.h
postalias.o: ../../include/set_eugid.h
postalias.o: ../../include/tok822.h
postalias.o: ../../include/resolve_clnt.h
postalias.o: ../../include/mail_conf.h

View File

@ -91,6 +91,7 @@ postmap.o: ../../include/readlline.h
postmap.o: ../../include/stringops.h
postmap.o: ../../include/split_at.h
postmap.o: ../../include/vstring_vstream.h
postmap.o: ../../include/set_eugid.h
postmap.o: ../../include/mail_conf.h
postmap.o: ../../include/mail_params.h
postmap.o: ../../include/mkmap.h

View File

@ -92,6 +92,7 @@ qmqpd.o: ../../include/namadr_list.h
qmqpd.o: ../../include/match_list.h
qmqpd.o: ../../include/match_ops.h
qmqpd.o: ../../include/quote_822_local.h
qmqpd.o: ../../include/quote_flags.h
qmqpd.o: ../../include/match_parent_style.h
qmqpd.o: ../../include/mail_server.h
qmqpd.o: qmqpd.h

View File

@ -328,7 +328,7 @@ static void qmqpd_write_content(QMQPD_STATE *state)
"\tby %s (%s) with %s id %s",
var_myhostname, var_mail_name,
state->protocol, state->queue_id);
quote_822_local(state->buf, state->recipient);
quote_822_local(state->buf, state->recipient, QUOTE_FLAG_8BITCLEAN);
rec_fprintf(state->cleanup, REC_TYPE_NORM,
"\tfor <%s>; %s", STR(state->buf), mail_date(state->time));
} else {

View File

@ -76,6 +76,7 @@ showq.o: ../../include/mail_conf.h
showq.o: ../../include/record.h
showq.o: ../../include/rec_type.h
showq.o: ../../include/quote_822_local.h
showq.o: ../../include/quote_flags.h
showq.o: ../../include/mail_addr.h
showq.o: ../../include/bounce_log.h
showq.o: ../../include/mail_server.h

View File

@ -137,7 +137,7 @@ static void showq_report(VSTREAM *client, char *queue, char *id,
case REC_TYPE_FROM:
if (*start == 0)
start = var_empty_addr;
quote_822_local(printable_quoted_addr, start);
quote_822_local(printable_quoted_addr, start, QUOTE_FLAG_8BITCLEAN);
printable(STR(printable_quoted_addr), '?');
vstream_fprintf(client, DATA_FORMAT, id, status,
msg_size > 0 ? msg_size : size, arrival_time > 0 ?
@ -147,7 +147,7 @@ static void showq_report(VSTREAM *client, char *queue, char *id,
case REC_TYPE_RCPT:
if (*start == 0) /* can't happen? */
start = var_empty_addr;
quote_822_local(printable_quoted_addr, start);
quote_822_local(printable_quoted_addr, start, QUOTE_FLAG_8BITCLEAN);
printable(STR(printable_quoted_addr), '?');
if (dup_filter == 0
|| htable_locate(dup_filter, STR(printable_quoted_addr)) == 0)

View File

@ -166,6 +166,7 @@ smtp_proto.o: ../../include/rec_type.h
smtp_proto.o: ../../include/off_cvt.h
smtp_proto.o: ../../include/mark_corrupt.h
smtp_proto.o: ../../include/quote_821_local.h
smtp_proto.o: ../../include/quote_flags.h
smtp_proto.o: smtp.h
smtp_proto.o: ../../include/argv.h
smtp_proto.o: smtp_sasl.h

View File

@ -305,7 +305,7 @@ int smtp_xfer(SMTP_STATE *state)
*/
#define REWRITE_ADDRESS(addr) do { \
if (*(addr)) { \
quote_821_local(state->scratch, addr); \
quote_821_local(state->scratch, addr, QUOTE_FLAG_8BITCLEAN); \
smtp_unalias_addr(state->scratch2, vstring_str(state->scratch)); \
myfree(addr); \
addr = mystrdup(vstring_str(state->scratch2)); \
@ -314,7 +314,7 @@ int smtp_xfer(SMTP_STATE *state)
#define QUOTE_ADDRESS(addr) do { \
if (*(addr)) { \
quote_821_local(state->scratch, addr); \
quote_821_local(state->scratch, addr, QUOTE_FLAG_8BITCLEAN); \
myfree(addr); \
addr = mystrdup(vstring_str(state->scratch)); \
} \

View File

@ -1020,6 +1020,12 @@ static int permit_auth_destination(SMTPD_STATE *state, char *recipient)
return (SMTPD_CHECK_OK);
domain += 1;
/*
* Skip source-routed non-local or virtual mail (uncertain destination).
*/
if (var_allow_untrust_route == 0 && (reply->flags & RESOLVE_FLAG_ROUTED))
return (SMTPD_CHECK_DUNNO);
/*
* Permit final delivery: the destination matches mydestination,
* virtual_maps, or virtual_mailbox_maps.
@ -1027,12 +1033,6 @@ static int permit_auth_destination(SMTPD_STATE *state, char *recipient)
if (resolve_final(state, recipient, domain))
return (SMTPD_CHECK_OK);
/*
* Skip source-routed mail (uncertain destination).
*/
if (var_allow_untrust_route == 0 && (reply->flags & RESOLVE_FLAG_ROUTED))
return (SMTPD_CHECK_DUNNO);
/*
* Permit if the destination matches the relay_domains list.
*/

View File

@ -76,6 +76,7 @@ resolve.o: ../../include/rewrite_clnt.h
resolve.o: ../../include/resolve_local.h
resolve.o: ../../include/mail_conf.h
resolve.o: ../../include/quote_822_local.h
resolve.o: ../../include/quote_flags.h
resolve.o: ../../include/tok822.h
resolve.o: ../../include/resolve_clnt.h
resolve.o: trivial-rewrite.h

View File

@ -97,8 +97,13 @@ void resolve_addr(char *addr, VSTRING *channel, VSTRING *nexthop,
/*
* The address is in internalized (unquoted) form, so we must externalize
* it first before we can parse it.
*
* While quoting the address local part, do not treat @ as a special
* character. This allows us to detect extra @ characters and block
* source routed relay attempts.
*/
quote_822_local(addr_buf, addr);
quote_822_local(addr_buf, addr,
QUOTE_FLAG_8BITCLEAN | QUOTE_FLAG_EXPOSE_AT);
tree = tok822_scan_addr(vstring_str(addr_buf));
/*

View File

@ -6,7 +6,7 @@
/* SYNOPSIS
/* #include <dict_db.h>
/*
/* int dict_db_mpool_size;
/* int dict_db_cache_size;
/*
/* DICT *dict_hash_open(path, open_flags, dict_flags)
/* const char *path;
@ -22,10 +22,10 @@
/* a pointer to a structure that can be used to access the dictionary
/* using the generic methods documented in dict_open(3).
/*
/* The dict_db_mpool_size variable specifies a non-default I/O buffer
/* size. The default buffer size is adequate for reading. For better
/* performance while creating a large table, specify a large buffer size
/* before opening the file.
/* The dict_db_cache_size variable specifies a non-default per-table
/* I/O buffer size. The default buffer size is adequate for reading.
/* For better performance while creating a large table, specify a large
/* buffer size before opening the file.
/*
/* Arguments:
/* .IP path
@ -112,7 +112,7 @@ typedef struct {
} DICT_DB;
/*
* You can override the default dict_db_mpool_size setting before calling
* You can override the default dict_db_cache_size setting before calling
* dict_hash_open() or dict_btree_open(). This is done in mkmap_db_open() to
* set a larger memory pool for database (re)builds.
*
@ -120,8 +120,9 @@ typedef struct {
* object property, instead of being specified by poking a global variable
* so that it becomes a class property.
*/
int dict_db_cache_size = (128 * 1024); /* 128K default memory pool */
#define DICT_DB_NELM 4096
int dict_db_mpool_size = (256 * 1024); /* 256K default memory pool */
#if DB_VERSION_MAJOR > 1
@ -154,89 +155,6 @@ static int sanitize(int status)
#endif
#if DB_VERSION_MAJOR > 1
static DB_ENV *dict_db_env;
static int dict_db_refcount;
/* dict_db_env_alloc - allocate shared environment */
static int dict_db_env_alloc(DB_ENV ** env)
{
int err;
/*
* Allocate a new environment if this is the first database. Bump the
* reference count so we can deallocate the environment when the last
* database is closed.
*/
if (dict_db_env != 0) {
++dict_db_refcount;
*env = dict_db_env;
return (0);
}
#if DB_VERSION_MAJOR == 2
#define DICT_DB_ENV_FLAGS (DB_CREATE|DB_INIT_MPOOL|DB_MPOOL_PRIVATE)
dict_db_env = (DB_ENV *) mymalloc(sizeof(DB_ENV));
memset((char *) dict_db_env, 0, sizeof(DB_ENV));
dict_db_env->mp_size = dict_db_mpool_size;
if ((err = db_appinit(0, 0, dict_db_env, DICT_DB_ENV_FLAGS)) != 0) {
myfree((char *) dict_db_env);
dict_db_env = 0;
return (err);
}
#endif /* DB_VERSION_MAJOR == 2 */
#if DB_VERSION_MAJOR > 2
#define DICT_DB_ENV_FLAGS (DB_CREATE|DB_INIT_MPOOL|DB_PRIVATE)
err = db_env_create(&dict_db_env, 0);
if (err == 0)
err = dict_db_env->set_cachesize(dict_db_env, 0, dict_db_mpool_size, 1);
if (err == 0)
err = dict_db_env->open(dict_db_env, 0, DICT_DB_ENV_FLAGS, 0644);
if (err != 0) {
if (dict_db_env)
dict_db_env->close(dict_db_env, 0);
dict_db_env = 0;
return (err);
}
#endif /* DB_VERSION_MAJOR > 2 */
++dict_db_refcount;
*env = dict_db_env;
return (0);
}
static void dict_db_env_free(void)
{
/*
* Deallocate a database within the environment Free the environment when
* the last database is closed
*/
#if DB_VERSION_MAJOR == 2
if (dict_db_env && dict_db_refcount > 0 && --dict_db_refcount == 0) {
db_appexit(dict_db_env);
myfree((char *) dict_db_env);
dict_db_env = 0;
}
#endif
#if DB_VERSION_MAJOR > 2
if (dict_db_env && dict_db_refcount > 0 && --dict_db_refcount == 0) {
dict_db_env->close(dict_db_env, 0);
dict_db_env = 0;
}
#endif
}
#endif /* DB_VERSION_MAJOR > 1 */
/* dict_db_lookup - find database entry */
static const char *dict_db_lookup(DICT *dict, const char *name)
@ -516,11 +434,6 @@ static void dict_db_close(DICT *dict)
msg_fatal("flush database %s: %m", dict_db->dict.name);
if (DICT_DB_CLOSE(dict_db->db) < 0)
msg_fatal("close database %s: %m", dict_db->dict.name);
#if DB_VERSION_MAJOR > 1
dict_db_env_free();
#endif
dict_free(dict);
}
@ -538,7 +451,6 @@ static DICT *dict_db_open(const char *class, const char *path, int open_flags,
#if DB_VERSION_MAJOR > 1
int db_flags;
DB_ENV *env;
#endif
@ -598,9 +510,7 @@ static DICT *dict_db_open(const char *class, const char *path, int open_flags,
db_flags |= DB_CREATE;
if (open_flags & O_TRUNC)
db_flags |= DB_TRUNCATE;
if ((errno = dict_db_env_alloc(&env)) != 0)
msg_fatal("create DB environment: %m");
if ((errno = db_open(db_path, type, db_flags, 0644, env, tweak, &db)) != 0)
if ((errno = db_open(db_path, type, db_flags, 0644, 0, tweak, &db)) != 0)
msg_fatal("open database %s: %m", db_path);
if (db == 0)
msg_panic("db_open null result");
@ -619,12 +529,12 @@ static DICT *dict_db_open(const char *class, const char *path, int open_flags,
db_flags |= DB_CREATE;
if (open_flags & O_TRUNC)
db_flags |= DB_TRUNCATE;
if ((errno = dict_db_env_alloc(&env)) != 0)
msg_fatal("create DB environment: %m");
if ((errno = db_create(&db, env, 0)) != 0)
if ((errno = db_create(&db, 0, 0)) != 0)
msg_fatal("create DB database: %m");
if (db == 0)
msg_panic("db_create null result");
if ((errno = db->set_cachesize(db, 0, dict_db_cache_size, 0)) != 0)
msg_fatal("set DB cache size %d: %m", dict_db_cache_size);
if (type == DB_HASH && db->set_h_nelem(db, DICT_DB_NELM) != 0)
msg_fatal("set DB hash element count %d: %m", DICT_DB_NELM);
if ((errno = db->open(db, db_path, 0, type, db_flags, 0644)) != 0)
@ -679,13 +589,14 @@ DICT *dict_hash_open(const char *path, int open_flags, int dict_flags)
memset((char *) &tweak, 0, sizeof(tweak));
tweak.nelem = DICT_DB_NELM;
tweak.cachesize = dict_db_mpool_size;
tweak.cachesize = dict_db_cache_size;
#endif
#if DB_VERSION_MAJOR == 2
DB_INFO tweak;
memset((char *) &tweak, 0, sizeof(tweak));
tweak.h_nelem = DICT_DB_NELM;
tweak.db_cachesize = dict_db_cache_size;
#endif
#if DB_VERSION_MAJOR > 2
void *tweak;
@ -704,12 +615,13 @@ DICT *dict_btree_open(const char *path, int open_flags, int dict_flags)
BTREEINFO tweak;
memset((char *) &tweak, 0, sizeof(tweak));
tweak.cachesize = dict_db_mpool_size;
tweak.cachesize = dict_db_cache_size;
#endif
#if DB_VERSION_MAJOR == 2
DB_INFO tweak;
memset((char *) &tweak, 0, sizeof(tweak));
tweak.db_cachesize = dict_db_cache_size;
#endif
#if DB_VERSION_MAJOR > 2
void *tweak;

View File

@ -28,7 +28,7 @@ extern DICT *dict_btree_open(const char *, int, int);
/*
* XXX Should be part of the DICT interface.
*/
extern int dict_db_mpool_size;
extern int dict_db_cache_size;
/* LICENSE
/* .ad

View File

@ -51,7 +51,7 @@ depend: $(MAKES)
$(CC) -E $(DEFS) $(INCL) $$i | sed -n -e '/^# *1 *"\([^"]*\)".*/{' \
-e 's//'`echo $$i|sed 's/c$$/o/'`': \1/' -e 'p' -e '}'; \
done) | grep -v '[.][o][:][ ][/]' >$$$$ && mv $$$$ Makefile.in
@$(EXPORT) @make -f Makefile.in Makefile
@$(EXPORT) make -f Makefile.in Makefile
# do not edit below this line - it is generated by 'make depend'
deliver_attr.o: deliver_attr.c