diff --git a/postfix/HISTORY b/postfix/HISTORY index 8928a7d0b..86c376ed9 100644 --- a/postfix/HISTORY +++ b/postfix/HISTORY @@ -2555,6 +2555,25 @@ Apologies for any names omitted. and for other mailer errors (error_notice_recipient). The default for all is "postmaster". +19990408 + + Workaround: on Solaris 2.x, the master appears to lose its + exclusive lock on the master.pid file, so keep grabbing + the lock each time the master wakes up from select(). + + Robustness: don't flush VSTREAM buffers after I/O error. + This prevents surprises when calling vstream_fclose() after + truncating a mailbox to its original size. + + Portability: on LINUX systems, if exists, don't + look for . + + Workaround: on Solaris 2.x, don't put an flock()/fcntl() lock + on mailboxes, to avoid clashes with the mailtool application. + + Portability: renamed readline to readlline, to avoid clashes + with mysql. + Future: Planned: must be able to list the same hash table in diff --git a/postfix/RELEASE_NOTES b/postfix/RELEASE_NOTES index 2a484bf80..19725e192 100644 --- a/postfix/RELEASE_NOTES +++ b/postfix/RELEASE_NOTES @@ -1,12 +1,60 @@ -Major changes with snapshot-19990322: +Incompatible changes with snapshot-19990408: +=========================================== + +- If an address extension (+foo) matches a user's .forward+foo file +name, the +foo extension is no longer appended to recipient addresses +listed in the .forward+foo file. This is more consistent with the +way Postfix expands aliases. + +Major changes with snapshot-19990408: ===================================== -- The UNIX-domain socket workaround for Solaris was fixed -after one day of review. More testing is welcome. +In addition to several little bugfixes, none related to security, +lots of internal code cleanup, lots of new functionality, and lots +of Solaris workarounds. -- reject_unknown_{sender,recipient}_domain restrictions that -distinguish between hard (always 450) and soft (configurable, -default 450) lookup errors. +- Regular expression support for all lookup tables, including access +control (full mail addresses only), address rewriting (canonical/virtual, +full mail addresses only) and transport tables (full domain names +only). However, regular expressions are not allowed for aliases. + +- POSIX regular expression support, enabled by default on 4.4BSD, +LINUX, and HP-UX. See conf/sample-regexp.cf. Initial code by Lamont +Jones, Hewlett-Packard, borrowing heavily from the PCRE implementation +by Andrew McNamara, connect.com.au Pty. Ltd., Australia. + +- forward_path configuration parameter for .forward files (default: +$home/.forward$recipient_delimiter$extension,$home/.forward). +Macros: $user (login name), $home (home directory), $recipient_delimiter, +$domain (recipient domain), and $extension (address extension). +Initial code by Philip A. Prindeville, Mirapoint, Inc., USA. + +- No more Postfix lockups on Solaris. The code no longer uses +Solaris UNIX-domain sockets, because they are still broken, +even with Solaris 7. + +- Workaround for the Solaris mailtool, which keeps an exclusive +fcntl/flock lock on the mailbox while its window is not iconified +(specify "deliver_lock_disable = yes" in main.cf). + +- Questionable workaround for Solaris, which reportedly loses +long-lived exclusive locks that are held by the master daemon. + +- New reject_unknown_{sender,recipient}_domain restrictions for +sender and recipient mail addresses that distinguish between soft +errors (always 450) and hard errors (unknown_address_reject_code, +default 450). + +- MIME-encapsulated bounce messages as per RFC 1892. Initial +implementation by Philip A. Prindeville, Mirapoint, Inc., USA. + +- Separately configurable "postmaster" addresses for single bounces +(bounce_notice_recipient), double bounces (2bounce_notice_recipient), +delayed mail (delay_notice_recipient), and for mailer error reports +(error_notice_recipient). See conf/main.cf. + +- Questionable feature: specify "best_mx_transport = local" if +this machine is the best MX host for domains not in mydestinations. Incompatible changes with postfix-19990317: =========================================== diff --git a/postfix/conf/main.cf.default b/postfix/conf/main.cf.default index dbb120309..6f6e351eb 100644 --- a/postfix/conf/main.cf.default +++ b/postfix/conf/main.cf.default @@ -30,6 +30,7 @@ delay_notice_recipient = postmaster delay_warning_time = 0 deliver_lock_attempts = 5 deliver_lock_delay = 1 +deliver_lock_disable = no disable_dns_lookups = no dont_remove = 0 double_bounce_sender = double-bounce @@ -60,7 +61,7 @@ luser_relay = mail_name = Postfix mail_owner = postfix mail_spool_directory = /var/mail -mail_version = Snapshot-19990407 +mail_version = Snapshot-19990408 mailbox_command = mailbox_transport = maps_rbl_domains = rbl.maps.vix.com diff --git a/postfix/conf/sample-local.cf b/postfix/conf/sample-local.cf index 840cc400f..889a102d9 100644 --- a/postfix/conf/sample-local.cf +++ b/postfix/conf/sample-local.cf @@ -26,8 +26,8 @@ # The forward_path parameter specifies a search list. The first file # that is found is used. In the path you can specify $user (login -# name), $home (home directory), $recipient_delimiter, and $extension -# (address extension). +# name), $home (home directory), $recipient_delimiter, $domain +# (recipient domain), and $extension (address extension). # #forward_path = /var/forward/$user forward_path = $home/.forward$recipient_delimiter$extension,$home/.forward diff --git a/postfix/conf/sample-misc.cf b/postfix/conf/sample-misc.cf index fb6544e71..f6a1a92c8 100644 --- a/postfix/conf/sample-misc.cf +++ b/postfix/conf/sample-misc.cf @@ -28,6 +28,15 @@ daemon_timeout = 18000 # default_transport = uucp default_transport = smtp +# The deliver_lock_disable parameter disables fcntl/flock file locking +# on mailboxes. This is needed on SUN workstations because the mailtool +# program keeps an exclusive fcntl/flock lock while its window is open. +# SUN software uses user.lock files only. Unless you remove all SUN +# mail software, fcntl/flock just gives a false sense of security. +# +#deliver_lock_disable = yes +deliver_lock_disable = no + # The double_bounce_sender parameter specifies the sender address # for mail that must be discarded when it cannot be delivered. This # must be a unique name. All mail to this name is silently discarded, diff --git a/postfix/conf/sample-smtp.cf b/postfix/conf/sample-smtp.cf index 90bf4d9c2..882f7394d 100644 --- a/postfix/conf/sample-smtp.cf +++ b/postfix/conf/sample-smtp.cf @@ -9,9 +9,10 @@ # local system is listed as the best MX host for a destination. By # default, Postfix reports a "mail loops back to myself" error and # bounces the message. Specify "best_mx_transport = local" to pass -# the mail to the local delivery agent. +# the mail to the local delivery agent. You can specify any transport +# that is defined in the master.cf file. # -best_mx_transport = +# best_mx_transport = # The fallback_relay parameter specifies zero or more hosts or domains # to hand off mail to if a message destination is not found, or if a diff --git a/postfix/contrib/regexp/pcre b/postfix/contrib/regexp/pcre deleted file mode 100644 index 21bcdbbd6..000000000 --- a/postfix/contrib/regexp/pcre +++ /dev/null @@ -1,565 +0,0 @@ -From owner-postfix-users@postfix.org Mon Mar 1 19:04:41 1999 -Delivered-To: wietse@porcupine.org -Received: from russian-caravan.cloud9.net (russian-caravan.cloud9.net [168.100.1.4]) - by spike.porcupine.org (Postfix) with ESMTP id 5785A45A72 - for ; Mon, 1 Mar 1999 19:04:36 -0500 (EST) -Received: by russian-caravan.cloud9.net (Postfix) - id 5F5D37638F; Mon, 1 Mar 1999 19:04:08 -0500 (EST) -Delivered-To: postfix-users-outgoing@cloud9.net -Received: by russian-caravan.cloud9.net (Postfix, from userid 54) - id 322AF76398; Mon, 1 Mar 1999 19:04:08 -0500 (EST) -Delivered-To: postfix-users@cloud9.net -Received: from melang.off.connect.com.au (melang.off.connect.com.au [202.21.9.1]) - by russian-caravan.cloud9.net (Postfix) with ESMTP id 6E87C7638F - for ; Mon, 1 Mar 1999 19:04:04 -0500 (EST) -Received: from connect.com.au (localhost [127.0.0.1]) - by melang.off.connect.com.au (Postfix) with ESMTP - id 074C7ED7D; Tue, 2 Mar 1999 11:04:02 +1100 (EST) -To: wietse@porcupine.org (Wietse Venema) -Cc: postfix-users@postfix.org (Postfix users) -Subject: regexp map patch -In-reply-to: Your message of "Thu, 25 Feb 1999 19:51:25 CDT." - <19990226005125.69B3C4596E@spike.porcupine.org> -Date: Tue, 02 Mar 1999 11:04:02 +1100 -From: Andrew McNamara -Message-Id: <19990302000403.074C7ED7D@melang.off.connect.com.au> -Sender: owner-postfix-users@postfix.org -Precedence: bulk -Return-Path: -Status: RO - -I've written a patch to add a regexp map type. It utilises the PCRE -library (Perl Compatible Regular Expressions), which can be obtained -from: - - ftp://ftp.cus.cam.ac.uk/pub/software/programs/pcre/ - -You will need to add -DHAS_PCRE and a -I for the PCRE header to CCARGS, -and add the path to the PCRE library to AUXLIBS, for example: - - make -f Makefile.init makefiles 'CCARGS=-DHAS_PCRE -I../../pcre-2.04' \ - 'AUXLIBS=../../pcre-2.04/libpcre.a' - -One possible use is to add a line to main.cf: - - smtpd_recipient_restrictions = regexp:/opt/postfix/etc/smtprecipient - -The regular expressions are read from the file specified and compiled - -a sample regexp file for this usage is included in the patch. - -Any feedback is appreciated (from Wietse in particular :-). Have fun. - -diff -u --recursive orig/postfix-beta-19990122-pl01/conf/sample-regexp postfix-beta-19990122-pl01/conf/sample-regexp ---- orig/postfix-beta-19990122-pl01/conf/sample-regexp Tue Mar 2 10:42:43 1999 -+++ postfix-beta-19990122-pl01/conf/sample-regexp Tue Mar 2 10:51:49 1999 -@@ -0,0 +1,51 @@ -+# -+# Sample regexp map source file -+# -+# The first field is a perl-like regular express. The expression -+# delimiter can be any character except whitespace, or characters -+# that have special meaning to the regexp library (traditionally -+# the forward slash is used). The expression can contain -+# whitespace. -+# -+# By default, matching is case-INsensative, although following -+# the second slash with an 'i' will reverse this. Other flags are -+# supported, but the only other useful one is 'U', which makes -+# matching ungreedy (see PCRE documentation and source for more -+# info). -+# -+# The second field is the "replacement" string - the text -+# returned by the match. When used for smtpd checks, this would -+# be a helpful message to misguided users (or an offensive -+# message to spammers), although it could also be a domain name -+# or other data for use as a transport, virtual, or other map. -+# -+# Substitution of sub-strings from the matched expression is -+# possible using the conventional perl syntax. The macros in the -+# replacement string may need to be protected with curly braces -+# if they aren't followed by whitespace (see the examples -+# below). -+# -+# If no second field is given, the text "REJECT" is returned - -+# this string is magic to the check functions in smtpd, and -+# results in an "administratively denied relay" message. -+# -+# Lines starting with whitespace are continuation lines - they are -+# appended to the previous line (there should be no whitespace -+# before your regular expression!) -+ -+ -+# Protect your outgoing majordomo exploders -+# -+/^(.*)-outgoing@(connect.com.au)$/ 550 Use ${1}@${2} instead -+ -+ -+# Bounce friend@whatever, except when whatever is our domain (you would -+# be better just bouncing all friend@ mail - this is just an example). -+# -+/^friend@(?!connect.com.au).*$/ 550 Stick this in your pipe $0 -+ -+# A multi-line response -+# -+/^noddy@connect.com.au$/ -+ 550 This user is a funny one. You really don't want to send mail to them -+ as it only makes their head spin. -diff -u --recursive orig/postfix-beta-19990122-pl01/util/Makefile.in postfix-beta-19990122-pl01/util/Makefile.in ---- orig/postfix-beta-19990122-pl01/util/Makefile.in Sun Jan 31 15:16:15 1999 -+++ postfix-beta-19990122-pl01/util/Makefile.in Fri Feb 26 15:57:24 1999 -@@ -18,7 +18,7 @@ - timed_wait.c translit.c trimblanks.c unix_connect.c unix_listen.c \ - unix_trigger.c unsafe.c username.c valid_hostname.c vbuf.c \ - vbuf_print.c vstream.c vstream_popen.c vstring.c vstring_vstream.c \ -- writable.c write_buf.c write_wait.c doze.c -+ writable.c write_buf.c write_wait.c doze.c dict_pcre.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_ni.o dict_nis.o \ -@@ -38,7 +38,7 @@ - timed_wait.o translit.o trimblanks.o unix_connect.o unix_listen.o \ - unix_trigger.o unsafe.o username.o valid_hostname.o vbuf.o \ - vbuf_print.o vstream.o vstream_popen.o vstring.o vstring_vstream.o \ -- writable.o write_buf.o write_wait.o doze.o -+ writable.o write_buf.o write_wait.o doze.o dict_pcre.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_ni.h dict_nis.h \ - dict_nisplus.h dir_forest.h events.h exec_command.h find_inet.h \ -@@ -51,7 +51,7 @@ - ring.h safe.h safe_open.h sane_accept.h scan_dir.h set_eugid.h \ - set_ugid.h sigdelay.h split_at.h stat_as.h stringops.h sys_defs.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 -+ vbuf.h vbuf_print.h vstream.h vstring.h vstring_vstream.h dict_pcre.h - TESTSRC = fifo_open.c fifo_rdwr_bug.c fifo_rdonly_bug.c - WARN = -W -Wformat -Wimplicit -Wmissing-prototypes \ - -Wparentheses -Wstrict-prototypes -Wswitch -Wuninitialized \ -diff -u --recursive orig/postfix-beta-19990122-pl01/util/dict_open.c postfix-beta-19990122-pl01/util/dict_open.c ---- orig/postfix-beta-19990122-pl01/util/dict_open.c Sat Dec 12 05:55:34 1998 -+++ postfix-beta-19990122-pl01/util/dict_open.c Fri Feb 26 15:07:51 1999 -@@ -100,6 +100,7 @@ - #include - #include - #include -+#include - #include - #include - -@@ -131,6 +132,9 @@ - #endif - #ifdef HAS_LDAP - "ldap", dict_ldap_open, -+#endif -+#ifdef HAS_PCRE -+ "regexp", dict_pcre_open, - #endif - 0, - }; -diff -u --recursive orig/postfix-beta-19990122-pl01/util/dict_pcre.c postfix-beta-19990122-pl01/util/dict_pcre.c ---- orig/postfix-beta-19990122-pl01/util/dict_pcre.c Tue Mar 2 10:42:30 1999 -+++ postfix-beta-19990122-pl01/util/dict_pcre.c Tue Mar 2 10:39:37 1999 -@@ -0,0 +1,349 @@ -+/*++ -+/* NAME -+/* dict_pcre 3 -+/* SUMMARY -+/* dictionary manager interface to PCRE regular expression library -+/* SYNOPSIS -+/* #include -+/* -+/* DICT *dict_pcre_open(name, flags) -+/* const char *name; -+/* int flags; -+/* DESCRIPTION -+/* dict_pcre_open() opens the named file and compiles the contained -+/* regular expressions. -+/* SEE ALSO -+/* dict(3) generic dictionary manager -+/* 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 -+/* -+/* Andrew McNamara -+/* andrewm@connect.com.au -+/* connect.com.au Pty. Ltd. -+/* Level 3, 213 Miller St -+/* North Sydney, NSW, Australia -+/*--*/ -+ -+#include "sys_defs.h" -+ -+#ifdef HAS_PCRE -+ -+/* System library. */ -+ -+#include /* sprintf() prototype */ -+#include -+#include -+#include -+#include -+ -+/* Utility library. */ -+ -+#include "mymalloc.h" -+#include "msg.h" -+#include "safe.h" -+#include "vstream.h" -+#include "vstring.h" -+#include "stringops.h" -+#include "readline.h" -+#include "dict.h" -+#include "dict_pcre.h" -+#include "mac_parse.h" -+ -+/* PCRE library */ -+ -+#include "pcre.h" -+ -+#define PCRE_MAX_CAPTURE 99 /* Max strings captured by regexp - */ -+ /* essentially the max number of (..) */ -+ -+struct dict_pcre_list { -+ pcre *pattern; /* The compiled pattern */ -+ pcre_extra *hints; /* Hints to speed pattern execution */ -+ char *replace; /* Replacement string */ -+ int lineno; /* Source file line number */ -+ struct dict_pcre_list *next; /* Next regexp in dict */ -+}; -+ -+typedef struct { -+ DICT dict; /* generic members */ -+ char *map; /* map name */ -+ int flags; /* unused at the moment */ -+ struct dict_pcre_list *head; -+} DICT_PCRE; -+ -+static dict_pcre_init = 0; /* flag need to init pcre library */ -+ -+/* -+ * dict_pcre_update - not supported -+ */ -+static void dict_pcre_update(DICT *dict, const char *unused_name, -+ const char *unused_value) -+{ -+ DICT_PCRE *dict_pcre = (DICT_PCRE *) dict; -+ -+ msg_fatal("dict_pcre_update: attempt to update regexp map %s", -+ dict_pcre->map); -+} -+ -+/* -+ * Context for macro expansion callback. -+ */ -+struct dict_pcre_context { -+ const char *dict_name; /* source dict name */ -+ int lineno; /* source file line number */ -+ VSTRING *buf; /* target string buffer */ -+ const char *subject; /* str against which we match */ -+ int offsets[ PCRE_MAX_CAPTURE * 3 ];/* Cut substrings */ -+ int matches; /* Count of cuts */ -+}; -+ -+/* -+ * Macro expansion callback - replace $0-${99} with strings cut from -+ * matched string. -+ */ -+static void dict_pcre_action( int type, VSTRING *buf, char *ptr ) -+{ -+ struct dict_pcre_context *ctxt = (struct dict_pcre_context *) ptr; -+ const char *pp; -+ int n, ret; -+ -+ if( type == MAC_PARSE_VARNAME ) { -+ n = atoi( vstring_str( buf )); -+ ret = pcre_get_substring( ctxt->subject, ctxt->offsets, ctxt->matches, -+ n, &pp ); -+ if( ret < 0 ) { -+ if( ret == PCRE_ERROR_NOSUBSTRING ) -+ msg_warn( "regexp %s, line %d: replace index out of range", -+ ctxt->dict_name, ctxt->lineno ); -+ else -+ msg_warn( "regexp %s, line %d: pcre_get_substring error: %d", -+ ctxt->dict_name, ctxt->lineno, ret ); -+ return; -+ } -+ vstring_strcat( ctxt->buf, pp ); -+ } else -+ /* Straight text - duplicate with no substitution */ -+ vstring_strcat( ctxt->buf, vstring_str(buf)); -+} -+ -+/* -+ * Look up regexp dict and perform string substitution on matched -+ * strings. -+ */ -+static const char *dict_pcre_lookup(DICT *dict, const char *name) -+{ -+ DICT_PCRE *dict_pcre = (DICT_PCRE *) dict; -+ struct dict_pcre_list *pcre_list; -+ int name_len = strlen( name ); -+ struct dict_pcre_context ctxt; -+ static VSTRING *buf; -+ -+/* msg_info("dict_pcre_lookup: %s: %s", dict_pcre->map, name );*/ -+ -+ /* Search for a matching expression */ -+ for( pcre_list = dict_pcre->head; pcre_list; pcre_list = pcre_list->next ) { -+ if( pcre_list->pattern ) { -+ ctxt.matches = pcre_exec( pcre_list->pattern, pcre_list->hints, -+ name, name_len, 0, ctxt.offsets, PCRE_MAX_CAPTURE * 3 ); -+ if( ctxt.matches != PCRE_ERROR_NOMATCH ) { -+ if( ctxt.matches > 0 ) -+ break; /* Got a match! */ -+ else { -+ /* An error */ -+ switch( ctxt.matches ) { -+ case 0: -+ msg_warn( "regexp map %s, line %d: too many (...)", -+ dict_pcre->map, pcre_list->lineno ); -+ break; -+ case PCRE_ERROR_NULL: -+ case PCRE_ERROR_BADOPTION: -+ msg_fatal( "regexp map %s, line %d: bad args to re_exec", -+ dict_pcre->map, pcre_list->lineno ); -+ break; -+ case PCRE_ERROR_BADMAGIC: -+ case PCRE_ERROR_UNKNOWN_NODE: -+ msg_fatal( "regexp map %s, line %d: corrupt compiled regexp", -+ dict_pcre->map, pcre_list->lineno ); -+ break; -+ default: -+ msg_fatal( "regexp map %s, line %d: unknown re_exec error: %d", -+ dict_pcre->map, pcre_list->lineno, ctxt.matches ); -+ break; -+ } -+ return( (char *)0 ); -+ } -+ } -+ } -+ } -+ -+ /* If we've got a match, */ -+ if ( ctxt.matches > 0 ) { -+ /* And we've got a replacement string, */ -+ if ( pcre_list->replace ) { -+ /* Then perform substitution on replacement string */ -+ if( buf == 0 ) -+ buf = vstring_alloc(10); -+ VSTRING_RESET(buf); -+ ctxt.buf = buf; -+ ctxt.subject = name; -+ ctxt.dict_name = dict_pcre->map; -+ ctxt.lineno = pcre_list->lineno; -+ -+ mac_parse( pcre_list->replace, dict_pcre_action, (char *)&ctxt ); -+ -+ VSTRING_TERMINATE(buf); -+ return( vstring_str( buf )); -+ } else -+ /* No replacement string, so just return dummy */ -+ return( "REJECT" ); -+ } -+ -+ return ( (char *)0 ); -+} -+ -+/* dict_pcre_close - close pcre dictionary */ -+ -+static void dict_pcre_close(DICT *dict) -+{ -+ DICT_PCRE *dict_pcre = (DICT_PCRE *) dict; -+ struct dict_pcre_list *pcre_list; -+ -+ for( pcre_list = dict_pcre->head; pcre_list; pcre_list = pcre_list->next ) { -+ if( pcre_list->pattern ) -+ myfree((char *) pcre_list->pattern); -+ if( pcre_list->hints ) -+ myfree((char *) pcre_list->hints); -+ if( pcre_list->replace ) -+ myfree((char *) pcre_list->replace); -+ } -+ myfree((char *) dict_pcre); -+} -+ -+/* -+ * dict_pcre_open - load and compile a file containing regular expressions -+ */ -+DICT *dict_pcre_open(const char *map, int unused_flags) -+{ -+ DICT_PCRE *dict_pcre; -+ VSTREAM *map_fp; -+ VSTRING *line_buffer; -+ struct dict_pcre_list *pcre_list = NULL, *pl; -+ int lineno = 0; -+ char *regexp, *p, re_delimiter; -+ int re_options; -+ pcre *pattern; -+ pcre_extra *hints; -+ const char *error; -+ int errptr; -+ -+ line_buffer = vstring_alloc(100); -+ -+ dict_pcre = (DICT_PCRE *) mymalloc(sizeof(*dict_pcre)); -+ dict_pcre->dict.lookup = dict_pcre_lookup; -+ dict_pcre->dict.update = dict_pcre_update; -+ dict_pcre->dict.close = dict_pcre_close; -+ dict_pcre->dict.fd = -1; -+ dict_pcre->map = mystrdup(map); -+ dict_pcre->flags = 0; -+ dict_pcre->head = NULL; -+ -+ if (dict_pcre_init == 0) { -+ pcre_malloc = (void *)mymalloc; -+ pcre_free = (void *)myfree; -+ dict_pcre_init = 1; -+ } -+ -+ if(( map_fp = vstream_fopen( map, O_RDONLY, 0 )) == 0 ) { -+ msg_fatal("open %s: %m", map ); -+ } -+ while (readline(line_buffer, map_fp, &lineno)) { -+ -+ if (*vstring_str(line_buffer) == '#') /* Skip comments */ -+ continue; -+ -+ p = vstring_str(line_buffer); -+ re_delimiter = *p++; -+ regexp = p; -+ -+ /* Search for second delimiter, handling backslash escape */ -+ while( *p ) { -+ if( *p == re_delimiter && -+ ( p > vstring_str(line_buffer) && *(p - 1) != '\\' )) -+ break; -+ ++p; -+ } -+ -+ if (!*p) { -+ msg_warn("%s, line %d: no closing regexp delimiter: %c", -+ VSTREAM_PATH(map_fp), lineno, re_delimiter ); -+ continue; -+ } -+ *p++ = '\0'; /* Null term the regexp */ -+ -+ /* Now parse any regexp options */ -+ re_options = PCRE_CASELESS; -+ while( *p && !ISSPACE( *p )) { -+ switch( *p ) { -+ case 'i': re_options ^= PCRE_CASELESS; break; -+ case 'm': re_options ^= PCRE_MULTILINE; break; -+ case 's': re_options ^= PCRE_DOTALL; break; -+ case 'x': re_options ^= PCRE_EXTENDED; break; -+ case 'A': re_options ^= PCRE_ANCHORED; break; -+ case 'E': re_options ^= PCRE_DOLLAR_ENDONLY; break; -+ case 'U': re_options ^= PCRE_UNGREEDY; break; -+ case 'X': re_options ^= PCRE_EXTRA; break; -+ default: -+ msg_warn("%s, line %d: unknown regexp option '%c'", -+ VSTREAM_PATH(map_fp), lineno, *p ); -+ } -+ ++p; -+ } -+ -+ while( *p && ISSPACE( *p )) -+ ++p; -+ -+ /* Compile the patern */ -+ pattern = pcre_compile( regexp, re_options, &error, &errptr, NULL ); -+ if( pattern == NULL ) { -+ msg_warn("%s, line %d: error in regex at offset %d: %s", -+ VSTREAM_PATH(map_fp), lineno, errptr, error ); -+ continue; -+ } -+ hints = pcre_study( pattern, 0, &error ); -+ if( error != NULL ) { -+ msg_warn("%s, line %d: error while studying regex: %s", -+ VSTREAM_PATH(map_fp), lineno, error ); -+ myfree( (char *)pattern ); -+ continue; -+ } -+ -+ /* Add it to the list */ -+ pl = (struct dict_pcre_list *)mymalloc( sizeof( struct dict_pcre_list )); -+ -+ /* Save the replacement string (if any) */ -+ pl->replace = ( *p ? mystrdup( p ) : NULL ); -+ pl->pattern = pattern; -+ pl->hints = hints; -+ pl->next = NULL; -+ pl->lineno = lineno; -+ -+ if( pcre_list == NULL ) -+ dict_pcre->head = pl; -+ else -+ pcre_list->next = pl; -+ pcre_list = pl; -+ } -+ -+ vstring_free(line_buffer); -+ vstream_fclose(map_fp); -+ -+ return (&dict_pcre->dict); -+} -+#endif /*HAS_PCRE*/ -diff -u --recursive orig/postfix-beta-19990122-pl01/util/dict_pcre.h postfix-beta-19990122-pl01/util/dict_pcre.h ---- orig/postfix-beta-19990122-pl01/util/dict_pcre.h Tue Mar 2 10:42:32 1999 -+++ postfix-beta-19990122-pl01/util/dict_pcre.h Mon Mar 1 18:17:23 1999 -@@ -0,0 +1,41 @@ -+#ifndef _DICT_PCRE_H_INCLUDED_ -+#define _DICT_PCRE_H_INCLUDED_ -+ -+/*++ -+/* NAME -+/* dict_pcre 3h -+/* SUMMARY -+/* dictionary manager interface to PCRE regular expression library -+/* SYNOPSIS -+/* #include -+/* DESCRIPTION -+/* .nf -+ -+ /* -+ * Utility library. -+ */ -+#include -+ -+ /* -+ * External interface. -+ */ -+extern DICT *dict_pcre_open(const char *, int); -+ -+/* 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 -+/* -+/* Andrew McNamara -+/* andrewm@connect.com.au -+/* connect.com.au Pty. Ltd. -+/* Level 3, 213 Miller St -+/* North Sydney, NSW, Australia -+/*--*/ -+ -+#endif - - --- -Andrew McNamara (Senior System Administrator) - -connect.com.au Pty Ltd -Lvl 3, 213 Miller St, North Sydney, NSW 2060, Australia -Phone: +61 2 9959 5959, Fax: +61 2 9966 1960 - - - diff --git a/postfix/global/deliver_flock.c b/postfix/global/deliver_flock.c index ef5559ba3..7d97dba04 100644 --- a/postfix/global/deliver_flock.c +++ b/postfix/global/deliver_flock.c @@ -26,6 +26,7 @@ /* CONFIGURATION PARAMETERS /* deliver_lock_attempts, number of locking attempts /* deliver_lock_delay, time in seconds between attempts +/* deliver_lock_disable, disable exclusive locking /* LICENSE /* .ad /* .fi @@ -58,6 +59,9 @@ int deliver_flock(int fd, VSTRING *why) { int i; + if (var_flock_disable) + return (0); + for (i = 0; /* void */ ; i++) { if (i >= var_flock_tries) break; diff --git a/postfix/global/mail_params.c b/postfix/global/mail_params.c index 7acf5e677..55862517b 100644 --- a/postfix/global/mail_params.c +++ b/postfix/global/mail_params.c @@ -51,6 +51,7 @@ /* int var_flock_tries; /* int var_flock_delay; /* int var_flock_stale; +/* int var_flock_disable; /* int var_disable_dns; /* int var_soft_bounce; /* time_t var_starttime; @@ -153,6 +154,7 @@ int var_fork_delay; int var_flock_tries; int var_flock_delay; int var_flock_stale; +int var_flock_disable; int var_disable_dns; int var_soft_bounce; time_t var_starttime; @@ -278,6 +280,7 @@ void mail_params_init() VAR_DISABLE_DNS, DEF_DISABLE_DNS, &var_disable_dns, VAR_SOFT_BOUNCE, DEF_SOFT_BOUNCE, &var_soft_bounce, VAR_OWNREQ_SPECIAL, DEF_OWNREQ_SPECIAL, &var_ownreq_special, + VAR_FLOCK_DISABLE, DEF_FLOCK_DISABLE, &var_flock_disable, 0, }; diff --git a/postfix/global/mail_params.h b/postfix/global/mail_params.h index bac96d26d..a91c0feca 100644 --- a/postfix/global/mail_params.h +++ b/postfix/global/mail_params.h @@ -631,6 +631,10 @@ extern int var_flock_delay; #define DEF_FLOCK_STALE 500 extern int var_flock_stale; +#define VAR_FLOCK_DISABLE "deliver_lock_disable" +#define DEF_FLOCK_DISABLE 0 +extern int var_flock_disable; + /* * How long a daemon command may take to receive or deliver a message etc. * before we assume it is wegded (should never happen). diff --git a/postfix/global/mail_version.h b/postfix/global/mail_version.h index f43e8f264..f4fb16867 100644 --- a/postfix/global/mail_version.h +++ b/postfix/global/mail_version.h @@ -15,7 +15,7 @@ * Version of this program. */ #define VAR_MAIL_VERSION "mail_version" -#define DEF_MAIL_VERSION "Snapshot-19990407" +#define DEF_MAIL_VERSION "Snapshot-19990408" extern char *var_mail_version; /* LICENSE diff --git a/postfix/local/Makefile.in b/postfix/local/Makefile.in index fabd97719..96972411b 100644 --- a/postfix/local/Makefile.in +++ b/postfix/local/Makefile.in @@ -380,7 +380,7 @@ token.o: ../include/vstring.h token.o: ../include/vbuf.h token.o: ../include/vstream.h token.o: ../include/htable.h -token.o: ../include/readline.h +token.o: ../include/readlline.h token.o: ../include/mymalloc.h token.o: ../include/vstring_vstream.h token.o: ../include/tok822.h diff --git a/postfix/local/token.c b/postfix/local/token.c index b3722f504..6f788a328 100644 --- a/postfix/local/token.c +++ b/postfix/local/token.c @@ -85,7 +85,7 @@ #include #include #include -#include +#include #include #include diff --git a/postfix/makedefs b/postfix/makedefs index 49512a2ee..14846374f 100644 --- a/postfix/makedefs +++ b/postfix/makedefs @@ -132,8 +132,7 @@ case "$SYSTEM.$RELEASE" in done if [ -f /usr/include/db_185.h ]; then CCARGS="$CCARGS -DPATH_DB_H=''" - fi - if [ -f /usr/include/db/db.h ]; then + elif [ -f /usr/include/db/db.h ]; then CCARGS="$CCARGS -DPATH_DB_H=''" fi ;; diff --git a/postfix/master/Makefile.in b/postfix/master/Makefile.in index f66a542ea..d2dcf052c 100644 --- a/postfix/master/Makefile.in +++ b/postfix/master/Makefile.in @@ -115,7 +115,7 @@ master_ent.o: ../include/vbuf.h master_ent.o: ../include/vstream.h master_ent.o: ../include/argv.h master_ent.o: ../include/stringops.h -master_ent.o: ../include/readline.h +master_ent.o: ../include/readlline.h master_ent.o: ../include/inet_addr_list.h master_ent.o: ../include/mail_proto.h master_ent.o: ../include/iostuff.h diff --git a/postfix/master/master.c b/postfix/master/master.c index 2343e3ae5..023f2c8c7 100644 --- a/postfix/master/master.c +++ b/postfix/master/master.c @@ -139,6 +139,7 @@ #include #include #include +#include /* Global library. */ @@ -331,6 +332,10 @@ int main(int argc, char **argv) */ signal(SIGALRM, master_watchdog); for (;;) { +#ifdef HAS_VOLATILE_LOCKS + if (myflock(vstream_fileno(lock_fp), MYFLOCK_EXCLUSIVE) < 0) + msg_fatal("refresh exclusive lock: %m"); +#endif alarm(1000); /* same as trigger servers */ event_loop(-1); if (master_gotsighup) { diff --git a/postfix/master/master_ent.c b/postfix/master/master_ent.c index b0f451c90..ae77491ca 100644 --- a/postfix/master/master_ent.c +++ b/postfix/master/master_ent.c @@ -82,7 +82,7 @@ #include #include #include -#include +#include #include /* Global library. */ @@ -237,7 +237,7 @@ MASTER_SERV *get_master_ent() * Skip blank lines and comment lines. */ do { - if (readline(buf, master_fp, &master_line) == 0) { + if (readlline(buf, master_fp, &master_line) == 0) { vstring_free(buf); vstring_free(junk); return (0); diff --git a/postfix/postalias/Makefile.in b/postfix/postalias/Makefile.in index c053f4015..795db706f 100644 --- a/postfix/postalias/Makefile.in +++ b/postfix/postalias/Makefile.in @@ -61,7 +61,7 @@ postalias.o: ../include/vstring.h postalias.o: ../include/vbuf.h postalias.o: ../include/vstream.h postalias.o: ../include/msg_vstream.h -postalias.o: ../include/readline.h +postalias.o: ../include/readlline.h postalias.o: ../include/stringops.h postalias.o: ../include/split_at.h postalias.o: ../include/get_hostname.h diff --git a/postfix/postalias/postalias.c b/postfix/postalias/postalias.c index 905d497ce..a3d7ffe89 100644 --- a/postfix/postalias/postalias.c +++ b/postfix/postalias/postalias.c @@ -105,7 +105,7 @@ #include #include #include -#include +#include #include #include #include @@ -160,7 +160,7 @@ static void postalias(char *map_type, char *path_name, * Add records to the database. */ lineno = 0; - while (readline(line_buffer, source_fp, &lineno)) { + while (readlline(line_buffer, source_fp, &lineno)) { /* * Skip comments. diff --git a/postfix/postmap/Makefile.in b/postfix/postmap/Makefile.in index ef896ce48..89f364f2e 100644 --- a/postfix/postmap/Makefile.in +++ b/postfix/postmap/Makefile.in @@ -61,7 +61,7 @@ postmap.o: ../include/vstring.h postmap.o: ../include/vbuf.h postmap.o: ../include/vstream.h postmap.o: ../include/msg_vstream.h -postmap.o: ../include/readline.h +postmap.o: ../include/readlline.h postmap.o: ../include/stringops.h postmap.o: ../include/split_at.h postmap.o: ../include/config.h diff --git a/postfix/postmap/postmap.c b/postfix/postmap/postmap.c index 21e88d12e..2aadc4d82 100644 --- a/postfix/postmap/postmap.c +++ b/postfix/postmap/postmap.c @@ -116,7 +116,7 @@ #include #include #include -#include +#include #include #include @@ -164,7 +164,7 @@ static void postmap(char *map_type, char *path_name, * Add records to the database. */ lineno = 0; - while (readline(line_buffer, source_fp, &lineno)) { + while (readlline(line_buffer, source_fp, &lineno)) { /* * Skip comments. diff --git a/postfix/util/Makefile.in b/postfix/util/Makefile.in index 1c2784b16..e50d1e623 100644 --- a/postfix/util/Makefile.in +++ b/postfix/util/Makefile.in @@ -12,7 +12,7 @@ SRCS = argv.c argv_split.c attr.c basename.c binhash.c chroot_uid.c \ msg_vstream.c mvect.c myflock.c mymalloc.c mystrtok.c name_mask.c \ non_blocking.c open_as.c open_limit.c open_lock.c peekfd.c \ percentm.c posix_signals.c printable.c read_wait.c readable.c \ - readline.c ring.c safe_getenv.c safe_open.c sane_accept.c \ + readlline.c ring.c safe_getenv.c safe_open.c sane_accept.c \ scan_dir.c set_eugid.c set_ugid.c sigdelay.c skipblanks.c \ split_at.c stat_as.c sys_compat.c timed_connect.c timed_wait.c \ translit.c trimblanks.c unix_connect.c unix_listen.c unix_trigger.c \ @@ -33,7 +33,7 @@ OBJS = argv.o argv_split.o attr.o basename.o binhash.o chroot_uid.o \ msg_vstream.o mvect.o myflock.o mymalloc.o mystrtok.o name_mask.o \ non_blocking.o open_as.o open_limit.o open_lock.o peekfd.o \ percentm.o posix_signals.o printable.o read_wait.o readable.o \ - readline.o ring.o safe_getenv.o safe_open.o sane_accept.o \ + readlline.o ring.o safe_getenv.o safe_open.o sane_accept.o \ scan_dir.o set_eugid.o set_ugid.o sigdelay.o skipblanks.o \ split_at.o stat_as.o sys_compat.o timed_connect.o timed_wait.o \ translit.o trimblanks.o unix_connect.o unix_listen.o unix_trigger.o \ @@ -49,7 +49,7 @@ HDRS = argv.h attr.h binhash.h chroot_uid.h connect.h dict.h dict_db.h \ iostuff.h line_wrap.h listen.h lstat_as.h mac_parse.h make_dirs.h \ match_list.h match_ops.h msg.h msg_output.h msg_syslog.h \ msg_vstream.h mvect.h myflock.h mymalloc.h name_mask.h open_as.h \ - open_lock.h percentm.h posix_signals.h readline.h ring.h safe.h \ + open_lock.h percentm.h posix_signals.h readlline.h ring.h safe.h \ safe_open.h sane_accept.h scan_dir.h set_eugid.h set_ugid.h \ sigdelay.h split_at.h stat_as.h stringops.h sys_defs.h \ timed_connect.h timed_wait.h trigger.h username.h valid_hostname.h \ @@ -290,7 +290,7 @@ dict.o: mymalloc.h dict.o: vstream.h dict.o: vbuf.h dict.o: vstring.h -dict.o: readline.h +dict.o: readlline.h dict.o: mac_parse.h dict.o: dict.h dict.o: dict_ht.h @@ -378,7 +378,7 @@ dict_regexp.o: vstream.h dict_regexp.o: vbuf.h dict_regexp.o: vstring.h dict_regexp.o: stringops.h -dict_regexp.o: readline.h +dict_regexp.o: readlline.h dict_regexp.o: dict.h dict_regexp.o: dict_regexp.h dict_regexp.o: mac_parse.h @@ -648,12 +648,12 @@ readable.o: readable.c readable.o: sys_defs.h readable.o: msg.h readable.o: iostuff.h -readline.o: readline.c -readline.o: sys_defs.h -readline.o: vstream.h -readline.o: vbuf.h -readline.o: vstring.h -readline.o: readline.h +readlline.o: readlline.c +readlline.o: sys_defs.h +readlline.o: vstream.h +readlline.o: vbuf.h +readlline.o: vstring.h +readlline.o: readlline.h ring.o: ring.c ring.o: ring.h safe_getenv.o: safe_getenv.c diff --git a/postfix/util/dict.c b/postfix/util/dict.c index 155515994..f6a1c5f53 100644 --- a/postfix/util/dict.c +++ b/postfix/util/dict.c @@ -139,7 +139,7 @@ #include "mymalloc.h" #include "vstream.h" #include "vstring.h" -#include "readline.h" +#include "readlline.h" #include "mac_parse.h" #include "dict.h" #include "dict_ht.h" @@ -308,7 +308,7 @@ void dict_load_fp(const char *dict_name, VSTREAM *fp) buf = vstring_alloc(100); lineno = 0; - while (readline(buf, fp, &lineno)) { + while (readlline(buf, fp, &lineno)) { start = STR(buf); SKIP(start, member, ISSPACE(*member)); /* find member begin */ if (*member == 0 || *member == '#') diff --git a/postfix/util/dict_pcre.c b/postfix/util/dict_pcre.c index a8d245862..67e53d17e 100644 --- a/postfix/util/dict_pcre.c +++ b/postfix/util/dict_pcre.c @@ -50,7 +50,7 @@ #include "vstream.h" #include "vstring.h" #include "stringops.h" -#include "readline.h" +#include "readlline.h" #include "dict.h" #include "dict_pcre.h" #include "mac_parse.h" @@ -263,7 +263,7 @@ DICT *dict_pcre_open(const char *map, int unused_flags, int dict_flags) if ((map_fp = vstream_fopen(map, O_RDONLY, 0)) == 0) { msg_fatal("open %s: %m", map); } - while (readline(line_buffer, map_fp, &lineno)) { + while (readlline(line_buffer, map_fp, &lineno)) { if (*vstring_str(line_buffer) == '#') /* Skip comments */ continue; diff --git a/postfix/util/dict_regexp.c b/postfix/util/dict_regexp.c index 6cc5696c7..9aeee007b 100644 --- a/postfix/util/dict_regexp.c +++ b/postfix/util/dict_regexp.c @@ -53,7 +53,7 @@ #include "vstream.h" #include "vstring.h" #include "stringops.h" -#include "readline.h" +#include "readlline.h" #include "dict.h" #include "dict_regexp.h" #include "mac_parse.h" @@ -372,7 +372,7 @@ DICT *dict_regexp_open(const char *map, int unused_flags, int dict_flags) if ((map_fp = vstream_fopen(map, O_RDONLY, 0)) == 0) { msg_fatal("open %s: %m", map); } - while (readline(line_buffer, map_fp, &lineno)) { + while (readlline(line_buffer, map_fp, &lineno)) { p = vstring_str(line_buffer); if (*p == '#') /* Skip comments */ diff --git a/postfix/util/readline.c b/postfix/util/readlline.c similarity index 84% rename from postfix/util/readline.c rename to postfix/util/readlline.c index c7a218f7e..8d71b85c6 100644 --- a/postfix/util/readline.c +++ b/postfix/util/readlline.c @@ -1,17 +1,17 @@ /*++ /* NAME -/* readline 3 +/* readlline 3 /* SUMMARY /* read logical line /* SYNOPSIS -/* #include +/* #include /* -/* VSTRING *readline(buf, fp, lineno) +/* VSTRING *readlline(buf, fp, lineno) /* VSTRING *buf; /* VSTREAM *fp; /* int *lineno; /* DESCRIPTION -/* readline() reads one logical line from the named stream. +/* readlline() reads one logical line from the named stream. /* A line that starts with whitespace is a continuation of /* the previous line. The newline between continued lines /* is deleted from the input. The result value is the input @@ -44,11 +44,11 @@ #include "vstream.h" #include "vstring.h" -#include "readline.h" +#include "readlline.h" -/* readline - read one logical line */ +/* readlline - read one logical line */ -VSTRING *readline(VSTRING *buf, VSTREAM *fp, int *lineno) +VSTRING *readlline(VSTRING *buf, VSTREAM *fp, int *lineno) { int ch; int next; diff --git a/postfix/util/readline.h b/postfix/util/readlline.h similarity index 82% rename from postfix/util/readline.h rename to postfix/util/readlline.h index dd6327002..8a8bd5487 100644 --- a/postfix/util/readline.h +++ b/postfix/util/readlline.h @@ -3,11 +3,11 @@ /*++ /* NAME -/* readline 3h +/* readlline 3h /* SUMMARY /* read logical line /* SYNOPSIS -/* #include +/* #include /* DESCRIPTION /* .nf @@ -20,7 +20,7 @@ /* * External interface. */ -extern VSTRING *readline(VSTRING *, VSTREAM *, int *); +extern VSTRING *readlline(VSTRING *, VSTREAM *, int *); /* LICENSE /* .ad diff --git a/postfix/util/sys_defs.h b/postfix/util/sys_defs.h index 3c1396348..f0a9f015b 100644 --- a/postfix/util/sys_defs.h +++ b/postfix/util/sys_defs.h @@ -156,6 +156,7 @@ extern int opterr; #define LOCAL_ACCEPT stream_accept #define LOCAL_CONNECT stream_connect #define LOCAL_TRIGGER stream_trigger +#define HAS_VOLATILE_LOCKS #endif #ifdef UW7 /* UnixWare 7 */ @@ -317,6 +318,7 @@ extern int h_errno; /* imports too much stuff */ #define USE_STATFS #define STATFS_IN_SYS_VFS_H +#define HAS_POSIX_REGEXP #endif #ifdef HPUX10 @@ -344,6 +346,7 @@ extern int h_errno; /* imports too much stuff */ #define USE_STATFS #define STATFS_IN_SYS_VFS_H +#define HAS_POSIX_REGEXP #endif #ifdef HPUX9 @@ -373,6 +376,7 @@ extern int h_errno; #define USE_ULIMIT /* no setrlimit() */ #define USE_STATFS #define STATFS_IN_SYS_VFS_H +#define HAS_POSIX_REGEXP #endif /* diff --git a/postfix/util/vstream.c b/postfix/util/vstream.c index f83b9ede3..7985ac32b 100644 --- a/postfix/util/vstream.c +++ b/postfix/util/vstream.c @@ -474,6 +474,8 @@ static int vstream_fflush_some(VSTREAM *stream, int to_flush) msg_panic("%s: to_flush < left_over", myname); if (to_flush == 0) return ((bp->flags & VSTREAM_FLAG_ERR) ? VSTREAM_EOF : 0); + if (bp->flags & VSTREAM_FLAG_ERR) + return (VSTREAM_EOF); /* * When flushing a buffer, allow for partial writes. These can happen