can do their own manual page processing. See scripts in
the mantools directory.
- Updated the reference to sendmail in the html/index.html page.
+ Documentation: updated the reference to sendmail in the
+ html/index.html page.
- Added note about the Cisco PIX "fixup smtp" bug when "."
- and "CRLF" arrive in separate packets. File: html/faq.html.
+ Documentation: added note about the Cisco PIX "fixup smtp"
+ bug that causes mail delivery problems when "." and "CRLF"
+ arrive in separate packets. File: html/faq.html.
+
+20010131
+
+ The code that reports a DNS lookup error now includes the
+ record type that was being looked up, so that people will
+ not misinterpret an MX lookup problem as an A record lookup
+ problem. File: dns/dns_lookup.c.
+
+20010201
+
+ Bugfix: another missing initialization in the mysql client.
+ File: util/dict_mysql.c.
+
+ Sanitized time routine by Patrik Rak, to make his nqmgr
+ robust against people who set their clock back. Files:
+ util/sane_time.[hc].
+
+ Bumped the default mailbox file size limits to 50MB.
the right-hand side of SMTPD access tables, so that you can have
different UCE restrictions for different clients or users.
-The only anomalies in this scheme are that (1) message header checks
-are still the same for every message, and (2) you must use a
-restriction class name (see below) if you want to specify a lookup
-table on the right-hand side of an access table (this is because
-Postfix needs to open those tables ahead of time).
+The only anomalies in this scheme are that (1) message header_checks
+and body_checks are still the same for every message, and (2) you
+must use a restriction class name (see below) if you want to specify
+a lookup table on the right-hand side of an access table (this is
+because Postfix needs to open those tables ahead of time).
Restriction classes allow you to give easy-to-remember names to
groups of UCE restrictions (such as permissive, restrictive, and
# The mailbox_size_limit parameter controls the maximal size of a
# mailbox or maildir file (in fact, it limits the size of any file
-# that is written to upon local delivery) The default is 20MBytes.
+# that is written to upon local delivery) The default is 50 MBytes.
# This limit must not be set smaller than the message size limit.
#
-mailbox_size_limit = 20480000
+mailbox_size_limit = 51200000
# The local_destination_recipient_limit parameter limits the number
# of recipients per local message delivery. The default limit is
s/[<bB>]*relocated[</bB>]*(5)/<a href="relocated.5.html">&<\/a>/
s/[<bB>]*trans[-</bB>]*\n*[ <bB>]*port[</bB>]*(5)/<a href="transport.5.html">&<\/a>/
s/[<bB>]*virtual[</bB>]*(5)/<a href="virtual.5.html">&<\/a>/
+ s/[<bB>]*virtual[</bB>]*(8)/<a href="virtual.8.html">&<\/a>/
s/RFC *\([0-9]*\)/<a href="http:\/\/www.faqs.org\/rfcs\/rfc\1.html">&<\/a>/
' "$@"
len = res_search((char *) name, C_IN, type, reply->buf, sizeof(reply->buf));
if (len < 0) {
if (why)
- vstring_sprintf(why, "Name service error for domain %s: %s",
- name, dns_strerror(h_errno));
+ vstring_sprintf(why, "Name service error for %s (%s) while looking up the %s record.",
+ name, dns_strerror(h_errno), dns_strtype(type));
if (msg_verbose)
msg_info("dns_query: %s (%s): %s",
name, dns_strtype(type), dns_strerror(h_errno));
#ifdef T_A
T_A, "A",
#endif
+#ifdef T_AAAA
+ T_AAAA, "AAAA",
+#endif
#ifdef T_NS
T_NS, "NS",
#endif
* the message size limit is implemented, but that is not clean.
*/
#define VAR_MAILBOX_LIMIT "mailbox_size_limit"
-#define DEF_MAILBOX_LIMIT (DEF_MESSAGE_LIMIT * 2)
+#define DEF_MAILBOX_LIMIT (DEF_MESSAGE_LIMIT * 5)
extern int var_mailbox_limit;
/*
extern char *var_virt_mailbox_base;
#define VAR_VIRT_MAILBOX_LIMIT "virtual_mailbox_limit"
-#define DEF_VIRT_MAILBOX_LIMIT (2 * DEF_MESSAGE_LIMIT)
+#define DEF_VIRT_MAILBOX_LIMIT (5 * DEF_MESSAGE_LIMIT)
extern int var_virt_mailbox_limit;
#define VAR_VIRT_MAILBOX_LOCK "virtual_mailbox_lock"
* Version of this program.
*/
#define VAR_MAIL_VERSION "mail_version"
-#define DEF_MAIL_VERSION "Snapshot-20010130"
+#define DEF_MAIL_VERSION "Snapshot-20010201"
extern char *var_mail_version;
/* LICENSE
maildir.o: ../../include/sane_fsops.h
maildir.o: ../../include/mail_copy.h
maildir.o: ../../include/bounce.h
+maildir.o: ../../include/defer.h
maildir.o: ../../include/sent.h
maildir.o: ../../include/mail_params.h
maildir.o: local.h
qmgr_job.o: qmgr_job.c
qmgr_job.o: ../../include/sys_defs.h
qmgr_job.o: ../../include/msg.h
-qmgr_job.o: ../../include/events.h
qmgr_job.o: ../../include/htable.h
qmgr_job.o: ../../include/mymalloc.h
+qmgr_job.o: ../../include/sane_time.h
qmgr_job.o: qmgr.h
qmgr_job.o: ../../include/vstream.h
qmgr_job.o: ../../include/vbuf.h
qmgr_message.o: qmgr_message.c
qmgr_message.o: ../../include/sys_defs.h
qmgr_message.o: ../../include/msg.h
-qmgr_message.o: ../../include/events.h
qmgr_message.o: ../../include/mymalloc.h
qmgr_message.o: ../../include/vstring.h
qmgr_message.o: ../../include/vbuf.h
qmgr_message.o: ../../include/argv.h
qmgr_message.o: ../../include/stringops.h
qmgr_message.o: ../../include/myflock.h
+qmgr_message.o: ../../include/sane_time.h
qmgr_message.o: ../../include/dict.h
qmgr_message.o: ../../include/mail_queue.h
qmgr_message.o: ../../include/mail_params.h
/* Utility library. */
#include <msg.h>
-#include <events.h>
#include <htable.h>
#include <mymalloc.h>
+#include <sane_time.h>
/* Application-specific. */
max_needed_entries,
max_total_entries;
int delay;
- time_t now = event_time();
+ time_t now = sane_time();
/*
* Fetch the result directly from the cache if the cache is still valid.
* And, because the leaf children are not ordered by the time since
* queued, we have to exclude them from the early loop end test.
*
- * By the way, the selection is reasonably resistant to OS time warping,
- * too.
- *
* However, don't bother searching if we can't find anything suitable
* anyway.
*/
/* Utility library. */
#include <msg.h>
-#include <events.h>
#include <mymalloc.h>
#include <vstring.h>
#include <vstream.h>
#include <argv.h>
#include <stringops.h>
#include <myflock.h>
+#include <sane_time.h>
/* Global library. */
message->refcount = 0;
message->single_rcpt = 0;
message->arrival_time = 0;
- message->queued_time = event_time();
+ message->queued_time = sane_time();
message->data_offset = 0;
message->queue_id = mystrdup(queue_id);
message->queue_name = mystrdup(queue_name);
stream_connect.c stream_trigger.c dict_regexp.c mac_expand.c \
clean_env.c watchdog.c spawn_command.c duplex_pipe.c sane_rename.c \
sane_link.c unescape.c timed_read.c timed_write.c dict_tcp.c \
- hex_quote.c dict_alloc.c rand_sleep.c
+ hex_quote.c dict_alloc.c rand_sleep.c sane_time.c
OBJS = argv.o argv_split.o attr.o basename.o binhash.o chroot_uid.o \
close_on_exec.o concatenate.o dict.o dict_db.o dict_dbm.o \
dict_env.o dict_ht.o dict_ldap.o dict_mysql.o dict_ni.o dict_nis.o \
stream_connect.o stream_trigger.o dict_regexp.o mac_expand.o \
clean_env.o watchdog.o spawn_command.o duplex_pipe.o sane_rename.o \
sane_link.o unescape.o timed_read.o timed_write.o dict_tcp.o \
- hex_quote.o dict_alloc.o rand_sleep.o
+ hex_quote.o dict_alloc.o rand_sleep.o sane_time.o
HDRS = argv.h attr.h binhash.h chroot_uid.h connect.h dict.h dict_db.h \
dict_dbm.h dict_env.h dict_ht.h dict_ldap.h dict_mysql.h \
dict_ni.h dict_nis.h dict_nisplus.h dir_forest.h events.h \
timed_connect.h timed_wait.h trigger.h username.h valid_hostname.h \
vbuf.h vbuf_print.h vstream.h vstring.h vstring_vstream.h \
dict_unix.h dict_pcre.h dict_regexp.h mac_expand.h clean_env.h \
- watchdog.h spawn_command.h sane_fsops.h dict_tcp.h hex_quote.h
+ watchdog.h spawn_command.h sane_fsops.h dict_tcp.h hex_quote.h \
+ sane_time.h
TESTSRC = fifo_open.c fifo_rdwr_bug.c fifo_rdonly_bug.c select_bug.c \
stream_test.c dup2_pass_on_exec.c
WARN = -W -Wformat -Wimplicit -Wmissing-prototypes \
inet_addr_host inet_addr_local mac_parse make_dirs msg_syslog \
mystrtok sigdelay translit valid_hostname vstream_popen \
vstring vstring_vstream doze select_bug stream_test mac_expand \
- watchdog unescape hex_quote name_mask rand_sleep
+ watchdog unescape hex_quote name_mask rand_sleep sane_time
LIB_DIR = ../../lib
INC_DIR = ../../include
$(CC) $(CFLAGS) -DTEST -o $@ $@.c $(LIB) $(SYSLIBS)
mv junk $@.o
+sane_time: $(LIB)
+ mv $@.o junk
+ $(CC) $(CFLAGS) -DTEST -o $@ $@.c $(LIB) $(SYSLIBS)
+ mv junk $@.o
+
depend: $(MAKES)
(sed '1,/^# do not edit/!d' Makefile.in; \
set -e; for i in [a-z][a-z0-9]*.c; do \
sane_rename.o: sys_defs.h
sane_rename.o: msg.h
sane_rename.o: sane_fsops.h
+sane_time.o: sane_time.c
+sane_time.o: sys_defs.h
+sane_time.o: msg.h
+sane_time.o: sane_time.h
scan_dir.o: scan_dir.c
scan_dir.o: sys_defs.h
scan_dir.o: msg.h
* parse the map's config file
* allocate memory
**********************************************************************/
-DICT *dict_mysql_open(const char *name, int unused_flags, int unused_dict_flags)
+DICT *dict_mysql_open(const char *name, int unused_open_flags, int dict_flags)
{
DICT_MYSQL *dict_mysql;
int connections;
sizeof(DICT_MYSQL));
dict_mysql->dict.lookup = dict_mysql_lookup;
dict_mysql->dict.close = dict_mysql_close;
+ dict_mysql->dict.flags = dict_flags | DICT_FLAG_FIXED;
dict_mysql->name = mysqlname_parse(name);
dict_mysql->pldb = plmysql_init(dict_mysql->name->hostnames,
dict_mysql->name->len_hosts);
--- /dev/null
+/*++
+/* NAME
+/* sane_time 3
+/* SUMMARY
+/* time(2) with backward time jump protection.
+/* SYNOPSIS
+/* #include <sane_time.h>
+/*
+/* time_t sane_time(void)
+/*
+/* DESCRIPTION
+/* This module provides time(2) like call for applications
+/* which need monotonically increasing time function rather
+/* than the real exact time. It eliminates the need for various
+/* workarounds all over the application which would handle
+/* potential problems if time suddenly jumps backward.
+/* Instead we choose to deal with this problem inside this
+/* module and let the application focus on its own tasks.
+/*
+/* sane_time() returns the current timestamp as obtained from
+/* time(2) call, at least most of the time. In case this routine
+/* detects that time has jumped backward, it keeps returning
+/* whatever timestamp it returned before, until this timestamp
+/* and the time(2) timestamp become synchronized again.
+/* Additionally, the returned timestamp is slowly increased to
+/* prevent the faked clock from freezing for too long.
+/* SEE ALSO
+/* time(2) get current time
+/* DIAGNOSTICS
+/* Warning message is logged if backward time jump is detected.
+/* LICENSE
+/* .ad
+/* .fi
+/* The Secure Mailer license must be distributed with this software.
+/* AUTHOR(S)
+/* Patrik Rak
+/* Modra 6
+/* 155 00, Prague, Czech Republic
+/*--*/
+
+/* System library. */
+
+#include <sys_defs.h>
+
+/* Utility library. */
+
+#include <msg.h>
+
+/* Application-specific. */
+
+#include "sane_time.h"
+
+/*
+ * How many times shall we slow down the real clock when recovering from
+ * time jump.
+ */
+#define SLEW_FACTOR 2
+
+/* sane_time - get current time, protected against time warping */
+
+time_t sane_time(void)
+{
+ time_t now;
+ static time_t last_time,
+ last_real;
+ int delta;
+ static int fraction;
+ static int warned;
+
+ now = time((time_t *) 0);
+
+ if ((delta = now - last_time) < 0 && last_time != 0) {
+ if ((delta = now - last_real) < 0) {
+ msg_warn("%sbackward time jump detected -- slewing clock",
+ warned++ ? "another " : "");
+ } else {
+ delta += fraction;
+ last_time += delta / SLEW_FACTOR;
+ fraction = delta % SLEW_FACTOR;
+ }
+ } else {
+ if (warned) {
+ warned = 0;
+ msg_warn("backward time jump recovered -- back to normality");
+ fraction = 0;
+ }
+ last_time = now;
+ }
+ last_real = now;
+
+ return (last_time);
+}
+
+#ifdef TEST
+
+ /*
+ * Proof-of-concept test program. Repeatedly print current system time and
+ * time returned by sane_time(). Meanwhile, try stepping your system clock
+ * back and forth to see what happens.
+ */
+
+#include <stdlib.h>
+#include <msg_vstream.h>
+#include <iostuff.h> /* doze() */
+
+int main(int argc, char **argv)
+{
+ int delay = 1000000;
+ time_t now;
+
+ msg_vstream_init(argv[0], VSTREAM_ERR);
+
+ if (argc == 2 && (delay = atol(argv[1]) * 1000) > 0)
+ /* void */ ;
+ else if (argc != 1)
+ msg_fatal("usage: %s [delay in ms (default 1 second)]", argv[0]);
+
+ for (;;) {
+ now = time((time_t *) 0);
+ vstream_printf("real: %s", ctime(&now));
+ now = sane_time();
+ vstream_printf("fake: %s\n", ctime(&now));
+ vstream_fflush(VSTREAM_OUT);
+ doze(delay);
+ }
+}
+
+#endif
--- /dev/null
+#ifndef _SANE_TIME_H_
+#define _SANE_TIME_H_
+
+/*++
+/* NAME
+/* sane_time 3h
+/* SUMMARY
+/* time(2) with backward time jump protection
+/* SYNOPSIS
+/* #include <sane_time.h>
+/* DESCRIPTION
+/* .nf
+
+ /*
+ * System library.
+ */
+#include <time.h>
+
+ /*
+ * External interface.
+ */
+extern time_t sane_time(void);
+
+/* LICENSE
+/* .ad
+/* .fi
+/* The Secure Mailer license must be distributed with this software.
+/* AUTHOR(S)
+/* Patrik Rak
+/* Modra 6
+/* 155 00, Prague, Czech Republic
+/*--*/
+
+#endif