From: Wietse Venema Date: Mon, 13 Mar 2006 05:00:00 +0000 (-0500) Subject: postfix-2.3-20060313 X-Git-Tag: v2.3-RC1~14 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=dc1096006169f65788bbccd102beaaf23bcd4e3e;p=thirdparty%2Fpostfix.git postfix-2.3-20060313 --- diff --git a/postfix/HISTORY b/postfix/HISTORY index 068783367..5ab5e8a0b 100644 --- a/postfix/HISTORY +++ b/postfix/HISTORY @@ -12023,8 +12023,31 @@ Apologies for any names omitted. processes. See also change 20060217. Files: postlock/postlock.c, master/multi_server.c, global/mail_run.c, util/vstream_popen.c. +20060310 + + Bugfix: the MIME processor assumed that input was null + terminated. This broke with CRLF input to the "sendmail -t" + command in Postfix 2.1 and later (see change 20030416). + Found by Leandro Santi. Based on patch by Victor Duchovni. + Files: global/mime_state.c, global/is_header.c. + +20060313 + + Cleanup: the message arrival time (start of the receive + transaction) no longer controls message expiration or + delivery attempts. Instead, expiration and delivery are + now controlled by the time when the cleanup server creates + a queue file. This closes a problem that was introduced + with the 20051104 change that introduced higher-resolution + delay time keeping: as a result, "postsuper -r" could no + longer manipulate the mail expiration schedule, so that + mail "on hold" could expire too soon. + Wish list: + The sendmail command should not return non-std exit status + after fatal error in some internal library routine. + Log DSN original recipient when rejecting mail. Keep whitespace between label and ":"? @@ -12082,11 +12105,6 @@ Wish list: dsb_formal -> dsb_form_all, dsb_status -> dsb_form_status - "postsuper -r" no longer resets the message arrival time, - because pickup(8) no longer overrides queue file time stamp - information. This can be a problem when mail "on hold" is - released after a long time. - Is it safe to cache a connection after it has been used for more than some number of address verification probes? diff --git a/postfix/html/postcat.1.html b/postfix/html/postcat.1.html index 22e4ecc9c..e5b841e23 100644 --- a/postfix/html/postcat.1.html +++ b/postfix/html/postcat.1.html @@ -21,7 +21,7 @@ POSTCAT(1) POSTCAT(1) Options: -c config_dir - The main.cf configuration file is in the named + The main.cf configuration file is in the named directory instead of the default configuration directory. @@ -44,15 +44,15 @@ POSTCAT(1) POSTCAT(1) Directory with Postfix configuration files. CONFIGURATION PARAMETERS - The following main.cf parameters are especially relevant + The following main.cf parameters are especially relevant to this program. The text below provides only a parameter summary. See postconf(5) for more details including examples. config_directory (see 'postconf -d' output) - The default location of the Postfix main.cf and - master.cf configuration files. + The default location of the Postfix main.cf and + master.cf configuration files. queue_directory (see 'postconf -d' output) The location of the Postfix top-level queue direc- diff --git a/postfix/src/cleanup/Makefile.in b/postfix/src/cleanup/Makefile.in index 3e09e7fe4..82681e1e1 100644 --- a/postfix/src/cleanup/Makefile.in +++ b/postfix/src/cleanup/Makefile.in @@ -194,7 +194,6 @@ cleanup_bounce.o: ../../include/cleanup_user.h cleanup_bounce.o: ../../include/deliver_request.h cleanup_bounce.o: ../../include/dict.h cleanup_bounce.o: ../../include/dsn.h -cleanup_bounce.o: ../../include/dsn_attr_map.h cleanup_bounce.o: ../../include/dsn_buf.h cleanup_bounce.o: ../../include/dsn_mask.h cleanup_bounce.o: ../../include/dsn_util.h @@ -214,6 +213,7 @@ cleanup_bounce.o: ../../include/msg.h cleanup_bounce.o: ../../include/msg_stats.h cleanup_bounce.o: ../../include/mymalloc.h cleanup_bounce.o: ../../include/nvtable.h +cleanup_bounce.o: ../../include/rec_attr_map.h cleanup_bounce.o: ../../include/rec_type.h cleanup_bounce.o: ../../include/recipient_list.h cleanup_bounce.o: ../../include/record.h @@ -232,7 +232,6 @@ cleanup_envelope.o: ../../include/attr.h cleanup_envelope.o: ../../include/been_here.h cleanup_envelope.o: ../../include/cleanup_user.h cleanup_envelope.o: ../../include/dict.h -cleanup_envelope.o: ../../include/dsn_attr_map.h cleanup_envelope.o: ../../include/dsn_mask.h cleanup_envelope.o: ../../include/header_opts.h cleanup_envelope.o: ../../include/htable.h @@ -249,6 +248,7 @@ cleanup_envelope.o: ../../include/msg.h cleanup_envelope.o: ../../include/mymalloc.h cleanup_envelope.o: ../../include/nvtable.h cleanup_envelope.o: ../../include/qmgr_user.h +cleanup_envelope.o: ../../include/rec_attr_map.h cleanup_envelope.o: ../../include/rec_type.h cleanup_envelope.o: ../../include/record.h cleanup_envelope.o: ../../include/resolve_clnt.h @@ -267,7 +267,6 @@ cleanup_extracted.o: ../../include/attr.h cleanup_extracted.o: ../../include/been_here.h cleanup_extracted.o: ../../include/cleanup_user.h cleanup_extracted.o: ../../include/dict.h -cleanup_extracted.o: ../../include/dsn_attr_map.h cleanup_extracted.o: ../../include/dsn_mask.h cleanup_extracted.o: ../../include/header_opts.h cleanup_extracted.o: ../../include/htable.h @@ -284,6 +283,7 @@ cleanup_extracted.o: ../../include/msg.h cleanup_extracted.o: ../../include/mymalloc.h cleanup_extracted.o: ../../include/nvtable.h cleanup_extracted.o: ../../include/qmgr_user.h +cleanup_extracted.o: ../../include/rec_attr_map.h cleanup_extracted.o: ../../include/rec_type.h cleanup_extracted.o: ../../include/record.h cleanup_extracted.o: ../../include/resolve_clnt.h diff --git a/postfix/src/cleanup/cleanup_bounce.c b/postfix/src/cleanup/cleanup_bounce.c index 6ca62967b..cc7ca9a64 100644 --- a/postfix/src/cleanup/cleanup_bounce.c +++ b/postfix/src/cleanup/cleanup_bounce.c @@ -52,7 +52,7 @@ #include #include #include -#include +#include /* Application-specific. */ @@ -147,8 +147,8 @@ int cleanup_bounce(CLEANUP_STATE *state) if (split_nameval(STR(buf), &attr_name, &attr_value) != 0 || *attr_value == 0) continue; - /* Map DSN attribute names to pseudo record type. */ - if ((junk = dsn_attr_map(attr_name)) != 0) { + /* Map attribute names to pseudo record type. */ + if ((junk = rec_attr_map(attr_name)) != 0) { start = attr_value; rec_type = junk; } diff --git a/postfix/src/cleanup/cleanup_envelope.c b/postfix/src/cleanup/cleanup_envelope.c index bd1f46e99..ba296e044 100644 --- a/postfix/src/cleanup/cleanup_envelope.c +++ b/postfix/src/cleanup/cleanup_envelope.c @@ -65,7 +65,7 @@ #include #include #include -#include +#include /* Application-specific. */ @@ -132,7 +132,6 @@ static void cleanup_envelope_process(CLEANUP_STATE *state, int type, state->flags |= extra_opts; return; } - #ifdef DELAY_ACTION if (type == REC_TYPE_DELAY) { /* Not part of queue file format. */ @@ -166,7 +165,7 @@ static void cleanup_envelope_process(CLEANUP_STATE *state, int type, state->queue_id, attr_name); return; } - if ((junk = dsn_attr_map(attr_name)) != 0) { + if ((junk = rec_attr_map(attr_name)) != 0) { mapped_buf = attr_value; mapped_type = junk; } @@ -317,12 +316,18 @@ static void cleanup_envelope_process(CLEANUP_STATE *state, int type, if (type == REC_TYPE_SIZE) /* Use our own SIZE record instead. */ return; + if (mapped_type == REC_TYPE_CTIME) + /* Use our own expiration time base record instead. */ + return; if (type == REC_TYPE_TIME) { /* First instance wins. */ if (state->arrival_time.tv_sec == 0) { REC_TYPE_TIME_SCAN(buf, state->arrival_time); cleanup_out(state, type, buf, len); } + /* Generate our own expiration time base record. */ + cleanup_out_format(state, REC_TYPE_ATTR, "%s=%ld", + MAIL_ATTR_CREATE_TIME, (long) time((time_t *) 0)); return; } if (type == REC_TYPE_FULL) { diff --git a/postfix/src/cleanup/cleanup_extracted.c b/postfix/src/cleanup/cleanup_extracted.c index 0ea738025..9f09b8dce 100644 --- a/postfix/src/cleanup/cleanup_extracted.c +++ b/postfix/src/cleanup/cleanup_extracted.c @@ -64,7 +64,7 @@ #include #include #include -#include +#include /* Application-specific. */ @@ -165,7 +165,7 @@ void cleanup_extracted_process(CLEANUP_STATE *state, int type, state->queue_id, attr_name); return; } - if ((junk = dsn_attr_map(attr_name)) != 0) { + if ((junk = rec_attr_map(attr_name)) != 0) { buf = attr_value; type = junk; } diff --git a/postfix/src/global/Makefile.in b/postfix/src/global/Makefile.in index 2a16d5f29..301412654 100644 --- a/postfix/src/global/Makefile.in +++ b/postfix/src/global/Makefile.in @@ -26,7 +26,7 @@ SRCS = abounce.c anvil_clnt.c been_here.c bounce.c bounce_log.c \ scache_clnt.c scache_multi.c user_acl.c mkmap_cdb.c mkmap_sdbm.c \ ehlo_mask.c \ wildcard_inet_addr.c valid_mailhost_addr.c dsn_util.c dsn_mask.c \ - dsn_attr_map.c dsn.c dsn_buf.c rcpt_buf.c rcpt_print.c dsn_print.c \ + rec_attr_map.c dsn.c dsn_buf.c rcpt_buf.c rcpt_print.c dsn_print.c \ dsb_scan.c mail_conf_long.c msg_stats_print.c msg_stats_scan.c \ conv_time.c OBJS = abounce.o anvil_clnt.o been_here.o bounce.o bounce_log.o \ @@ -56,7 +56,7 @@ OBJS = abounce.o anvil_clnt.o been_here.o bounce.o bounce_log.o \ scache_clnt.o scache_multi.o user_acl.o mkmap_cdb.o mkmap_sdbm.o \ ehlo_mask.o \ wildcard_inet_addr.o valid_mailhost_addr.o dsn_util.o dsn_mask.o \ - dsn_attr_map.o dsn.o dsn_buf.o rcpt_buf.o rcpt_print.o dsn_print.o \ + rec_attr_map.o dsn.o dsn_buf.o rcpt_buf.o rcpt_print.o dsn_print.o \ dsb_scan.o mail_conf_long.o msg_stats_print.o msg_stats_scan.o \ conv_time.o HDRS = abounce.h anvil_clnt.h been_here.h bounce.h bounce_log.h \ @@ -81,7 +81,7 @@ HDRS = abounce.h anvil_clnt.h been_here.h bounce.h bounce_log.h \ trace.h verify.h verify_clnt.h verp_sender.h \ xtext.h scache.h user_acl.h ehlo_mask.h db_common.h \ wildcard_inet_addr.h valid_mailhost_addr.h dsn_util.h dsn_mask.h \ - dsn_attr_map.h dsn.h dsn_buf.h rcpt_buf.h rcpt_print.h dsn_print.h \ + rec_attr_map.h dsn.h dsn_buf.h rcpt_buf.h rcpt_print.h dsn_print.h \ dsb_scan.h msg_stats.h conv_time.h TESTSRC = rec2stream.c stream2rec.c recdump.c DEFS = -I. -I$(INC_DIR) -D$(SYSTYPE) @@ -780,15 +780,6 @@ dsn.o: ../../include/mymalloc.h dsn.o: ../../include/sys_defs.h dsn.o: dsn.c dsn.o: dsn.h -dsn_attr_map.o: ../../include/attr.h -dsn_attr_map.o: ../../include/iostuff.h -dsn_attr_map.o: ../../include/sys_defs.h -dsn_attr_map.o: ../../include/vbuf.h -dsn_attr_map.o: ../../include/vstream.h -dsn_attr_map.o: dsn_attr_map.c -dsn_attr_map.o: dsn_attr_map.h -dsn_attr_map.o: mail_proto.h -dsn_attr_map.o: rec_type.h dsn_buf.o: ../../include/msg.h dsn_buf.o: ../../include/mymalloc.h dsn_buf.o: ../../include/sys_defs.h @@ -1501,6 +1492,15 @@ rec2stream.o: rec2stream.c rec2stream.o: rec_streamlf.h rec2stream.o: rec_type.h rec2stream.o: record.h +rec_attr_map.o: ../../include/attr.h +rec_attr_map.o: ../../include/iostuff.h +rec_attr_map.o: ../../include/sys_defs.h +rec_attr_map.o: ../../include/vbuf.h +rec_attr_map.o: ../../include/vstream.h +rec_attr_map.o: mail_proto.h +rec_attr_map.o: rec_attr_map.c +rec_attr_map.o: rec_attr_map.h +rec_attr_map.o: rec_type.h rec_streamlf.o: ../../include/sys_defs.h rec_streamlf.o: ../../include/vbuf.h rec_streamlf.o: ../../include/vstream.h diff --git a/postfix/src/global/is_header.c b/postfix/src/global/is_header.c index bc21e4b20..1bf93a4c6 100644 --- a/postfix/src/global/is_header.c +++ b/postfix/src/global/is_header.c @@ -6,12 +6,19 @@ /* SYNOPSIS /* #include /* -/* int is_header(string) +/* ssize_t is_header(string) /* const char *string; +/* +/* ssize_t is_header_buf(string, len) +/* const char *string; +/* ssize_t len; /* DESCRIPTION /* is_header() examines the given string and returns non-zero (true) /* when it begins with a mail header name + optional space + colon. /* The result is the length of the mail header name. +/* +/* is_header_buf() is a more elaborate interface for use with strings +/* that may not be null terminated. /* STANDARDS /* RFC 822 (ARPA Internet Text Messages) /* LICENSE @@ -34,14 +41,14 @@ #include "is_header.h" -/* is_header - determine if this can be a header line */ +/* is_header_buf - determine if this can be a header line */ -int is_header(const char *str) +ssize_t is_header_buf(const char *str, ssize_t str_len) { const unsigned char *cp; int state; int c; - int len; + ssize_t len; #define INIT 0 #define IN_CHAR 1 @@ -51,11 +58,16 @@ int is_header(const char *str) /* * XXX RFC 2822 Section 4.5, Obsolete header fields: whitespace may * appear between header label and ":" (see: RFC 822, Section 3.4.2.). + * + * XXX Don't run off the end in case some non-standard iscntrl() + * implementation considers null a non-control character... */ - for (len = 0, state = INIT, cp = CU_CHAR_PTR(str); (c = *cp) != 0; cp++) { - switch (c) { + for (len = 0, state = INIT, cp = CU_CHAR_PTR(str); /* see below */; cp++) { + if (str_len != IS_HEADER_NULL_TERMINATED && str_len-- <= 0) + return (0); + switch (c = *cp) { default: - if (!ISASCII(c) || ISCNTRL(c)) + if (c == 0 || !ISASCII(c) || ISCNTRL(c)) return (0); if (state == INIT) state = IN_CHAR; diff --git a/postfix/src/global/is_header.h b/postfix/src/global/is_header.h index 0fc6bd38b..e42957fc3 100644 --- a/postfix/src/global/is_header.h +++ b/postfix/src/global/is_header.h @@ -13,7 +13,10 @@ /* External interface. */ -extern int is_header(const char *); +#define IS_HEADER_NULL_TERMINATED (-1) +#define is_header(str) is_header_buf(str, IS_HEADER_NULL_TERMINATED) + +extern ssize_t is_header_buf(const char *, ssize_t); /* LICENSE /* .ad diff --git a/postfix/src/global/mail_conf_time.ref b/postfix/src/global/mail_conf_time.ref index d6ef0b1e0..94948568b 100644 --- a/postfix/src/global/mail_conf_time.ref +++ b/postfix/src/global/mail_conf_time.ref @@ -1,4 +1,4 @@ -10 seconds = 1 +10 seconds = 10 10 minutes = 600 10 hours = 36000 10 days = 864000 diff --git a/postfix/src/global/mail_proto.h b/postfix/src/global/mail_proto.h index 6e5855287..232b5ffe5 100644 --- a/postfix/src/global/mail_proto.h +++ b/postfix/src/global/mail_proto.h @@ -109,6 +109,7 @@ extern char *mail_pathname(const char *, const char *); #define MAIL_ATTR_ERRTO "errors-to" #define MAIL_ATTR_RRCPT "return-receipt" #define MAIL_ATTR_TIME "time" +#define MAIL_ATTR_CREATE_TIME "create_time" #define MAIL_ATTR_RULE "rule" #define MAIL_ATTR_ADDR "address" #define MAIL_ATTR_TRANSPORT "transport" diff --git a/postfix/src/global/mail_version.h b/postfix/src/global/mail_version.h index a13886bb5..7b3dd946c 100644 --- a/postfix/src/global/mail_version.h +++ b/postfix/src/global/mail_version.h @@ -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 "20060307" +#define MAIL_RELEASE_DATE "20060313" #define MAIL_VERSION_NUMBER "2.3" #ifdef SNAPSHOT diff --git a/postfix/src/global/mime_state.c b/postfix/src/global/mime_state.c index 31c166508..8988ad5bb 100644 --- a/postfix/src/global/mime_state.c +++ b/postfix/src/global/mime_state.c @@ -766,7 +766,7 @@ int mime_state_update(MIME_STATE *state, int rec_type, if (input_is_text) { if (state->prev_rec_type == REC_TYPE_CONT) { if (LEN(state->output_buffer) < var_header_limit) { - vstring_strcat(state->output_buffer, text); + vstring_strncat(state->output_buffer, text, len); } else { if (state->static_flags & MIME_OPT_REPORT_TRUNC_HEADER) REPORT_ERROR(state, MIME_ERR_TRUNC_HEADER, @@ -777,7 +777,7 @@ int mime_state_update(MIME_STATE *state, int rec_type, if (IS_SPACE_TAB(*text)) { if (LEN(state->output_buffer) < var_header_limit) { vstring_strcat(state->output_buffer, "\n"); - vstring_strcat(state->output_buffer, text); + vstring_strncat(state->output_buffer, text, len); } else { if (state->static_flags & MIME_OPT_REPORT_TRUNC_HEADER) REPORT_ERROR(state, MIME_ERR_TRUNC_HEADER, @@ -832,18 +832,23 @@ int mime_state_update(MIME_STATE *state, int rec_type, * clean slate. */ if (input_is_text) { - int header_len; + ssize_t header_len; /* * See if this input is (the beginning of) a message header. + * * Normalize obsolete "name space colon" syntax to "name colon". * Things would be too confusing otherwise. + * + * Don't assume that the input is null terminated. */ - if ((header_len = is_header(text)) > 0) { + if ((header_len = is_header_buf(text, len)) > 0) { vstring_strncpy(state->output_buffer, text, header_len); - for (text += header_len; IS_SPACE_TAB(*text); text++) + for (text += header_len, len -= header_len; + len > 0 && IS_SPACE_TAB(*text); + text++, len--) /* void */ ; - vstring_strcat(state->output_buffer, text); + vstring_strncat(state->output_buffer, text, len); SAVE_PREV_REC_TYPE_AND_RETURN_ERR_FLAGS(state, rec_type); } } @@ -914,9 +919,11 @@ int mime_state_update(MIME_STATE *state, int rec_type, * * XXX This changes state to MIME_STATE_NESTED and then outputs a body * line, so that the body offset is not properly reset. + * + * Don't assume that the input is null terminated. */ if (input_is_text) { - if (*text == 0) { + if (len == 0) { state->body_offset = 0; /* XXX */ if (state->curr_ctype == MIME_CTYPE_MESSAGE) { if (state->curr_stype == MIME_STYPE_RFC822 @@ -973,6 +980,8 @@ int mime_state_update(MIME_STATE *state, int rec_type, * string. * * Don't look for boundary strings at the start of a continued record. + * + * Don't assume that the input is null terminated. */ case MIME_STATE_BODY: if (input_is_text) { @@ -986,12 +995,14 @@ int mime_state_update(MIME_STATE *state, int rec_type, } } if (state->stack && state->prev_rec_type != REC_TYPE_CONT - && text[0] == '-' && text[1] == '-') { + && len > 2 && text[0] == '-' && text[1] == '-') { for (sp = state->stack; sp != 0; sp = sp->next) { - if (strncmp(text + 2, sp->boundary, sp->bound_len) == 0) { + if (len >= 2 + sp->bound_len && + strncmp(text + 2, sp->boundary, sp->bound_len) == 0) { while (sp != state->stack) mime_state_pop(state); - if (strncmp(text + 2 + sp->bound_len, "--", 2) == 0) { + if (len >= 4 + sp->bound_len && + strncmp(text + 2 + sp->bound_len, "--", 2) == 0) { mime_state_pop(state); SET_MIME_STATE(state, MIME_STATE_BODY, MIME_CTYPE_OTHER, MIME_STYPE_OTHER, diff --git a/postfix/src/global/dsn_attr_map.c b/postfix/src/global/rec_attr_map.c similarity index 69% rename from postfix/src/global/dsn_attr_map.c rename to postfix/src/global/rec_attr_map.c index 481722d55..e98dde814 100644 --- a/postfix/src/global/dsn_attr_map.c +++ b/postfix/src/global/rec_attr_map.c @@ -1,15 +1,15 @@ /*++ /* NAME -/* dsn_attr_map 3 +/* rec_attr_map 3 /* SUMMARY -/* map named attribute to pseudo record type +/* map named attribute record type to pseudo record type /* SYNOPSIS -/* #include +/* #include /* -/* int dsn_attr_map(attr_name) +/* int rec_attr_map(attr_name) /* const char *attr_name; /* DESCRIPTION -/* dsn_attr_map() maps the record type of a named attribute to +/* rec_attr_map() maps the record type of a named attribute to /* a pseudo record type, if such a mapping exists. The result /* is the pseudo record type in case of success, 0 on failure. /* LICENSE @@ -32,11 +32,11 @@ #include #include -#include +#include -/* dsn_attr_map - map named attribute to pseudo record type */ +/* rec_attr_map - map named attribute to pseudo record type */ -int dsn_attr_map(const char *attr_name) +int rec_attr_map(const char *attr_name) { if (strcmp(attr_name, MAIL_ATTR_DSN_ORCPT) == 0) { return (REC_TYPE_DSN_ORCPT); @@ -46,6 +46,8 @@ int dsn_attr_map(const char *attr_name) return (REC_TYPE_DSN_ENVID); } else if (strcmp(attr_name, MAIL_ATTR_DSN_RET) == 0) { return (REC_TYPE_DSN_RET); + } else if (strcmp(attr_name, MAIL_ATTR_CREATE_TIME) == 0) { + return (REC_TYPE_CTIME); } else { return (0); } diff --git a/postfix/src/global/dsn_attr_map.h b/postfix/src/global/rec_attr_map.h similarity index 59% rename from postfix/src/global/dsn_attr_map.h rename to postfix/src/global/rec_attr_map.h index ee2d58206..ae57cf128 100644 --- a/postfix/src/global/dsn_attr_map.h +++ b/postfix/src/global/rec_attr_map.h @@ -1,20 +1,20 @@ -#ifndef _DSN_ATTR_MAP_H_INCLUDED_ -#define _DSN_ATTR_MAP_H_INCLUDED_ +#ifndef _REC_ATTR_MAP_H_INCLUDED_ +#define _REC_ATTR_MAP_H_INCLUDED_ /*++ /* NAME -/* dsn_attr_map 3h +/* rec_attr_map 3h /* SUMMARY -/* map named attribute to pseudo record type +/* map named attribute record type to pseudo record type /* SYNOPSIS -/* #include +/* #include /* DESCRIPTION /* .nf /* * External interface. */ -extern int dsn_attr_map(const char *); +extern int rec_attr_map(const char *); /* LICENSE /* .ad diff --git a/postfix/src/global/rec_type.c b/postfix/src/global/rec_type.c index 268c49d2b..0ed52ef85 100644 --- a/postfix/src/global/rec_type.c +++ b/postfix/src/global/rec_type.c @@ -42,6 +42,7 @@ REC_TYPE_NAME rec_type_names[] = { REC_TYPE_ERROR, "error", /* not Postfix-specific. */ REC_TYPE_SIZE, "message_size", REC_TYPE_TIME, "message_arrival_time", + REC_TYPE_CTIME, "queue_file_create_time", REC_TYPE_FULL, "sender_fullname", REC_TYPE_INSP, "content_inspector", REC_TYPE_FILT, "content_filter", diff --git a/postfix/src/global/rec_type.h b/postfix/src/global/rec_type.h index ead079964..28dea627a 100644 --- a/postfix/src/global/rec_type.h +++ b/postfix/src/global/rec_type.h @@ -35,7 +35,8 @@ * constant, and it is too late to change that now. */ #define REC_TYPE_SIZE 'C' /* first record, created by cleanup */ -#define REC_TYPE_TIME 'T' /* time stamp, required */ +#define REC_TYPE_TIME 'T' /* arrival time, required */ +#define REC_TYPE_CTIME 'c' /* create time, optional */ #define REC_TYPE_FULL 'F' /* full name, optional */ #define REC_TYPE_INSP 'I' /* inspector transport */ #define REC_TYPE_FILT 'L' /* loop filter transport */ @@ -94,7 +95,7 @@ * Note: REC_TYPE_FILT and REC_TYPE_CONT are encoded with the same 'L' * constant, and it is too late to change that now. */ -#define REC_TYPE_ENVELOPE "MCTFILSDROWVA>KKKon" diff --git a/postfix/src/oqmgr/Makefile.in b/postfix/src/oqmgr/Makefile.in index c057c492f..66fb73e3f 100644 --- a/postfix/src/oqmgr/Makefile.in +++ b/postfix/src/oqmgr/Makefile.in @@ -200,7 +200,6 @@ qmgr_message.o: ../../include/deliver_completed.h qmgr_message.o: ../../include/deliver_request.h qmgr_message.o: ../../include/dict.h qmgr_message.o: ../../include/dsn.h -qmgr_message.o: ../../include/dsn_attr_map.h qmgr_message.o: ../../include/dsn_buf.h qmgr_message.o: ../../include/dsn_mask.h qmgr_message.o: ../../include/iostuff.h @@ -213,6 +212,7 @@ qmgr_message.o: ../../include/myflock.h qmgr_message.o: ../../include/mymalloc.h qmgr_message.o: ../../include/opened.h qmgr_message.o: ../../include/qmgr_user.h +qmgr_message.o: ../../include/rec_attr_map.h qmgr_message.o: ../../include/rec_type.h qmgr_message.o: ../../include/recipient_list.h qmgr_message.o: ../../include/record.h diff --git a/postfix/src/oqmgr/qmgr.h b/postfix/src/oqmgr/qmgr.h index 5966b8df8..383f0ec24 100644 --- a/postfix/src/oqmgr/qmgr.h +++ b/postfix/src/oqmgr/qmgr.h @@ -209,7 +209,8 @@ struct QMGR_MESSAGE { VSTREAM *fp; /* open queue file or null */ int refcount; /* queue entries */ int single_rcpt; /* send one rcpt at a time */ - struct timeval arrival_time; /* time when queued */ + struct timeval arrival_time; /* start of receive transaction */ + time_t create_time; /* queue file create time */ struct timeval active_time; /* time of entry into active queue */ long warn_offset; /* warning bounce flag offset */ time_t warn_time; /* time next warning to be sent */ diff --git a/postfix/src/oqmgr/qmgr_active.c b/postfix/src/oqmgr/qmgr_active.c index b2136b1e9..67320c570 100644 --- a/postfix/src/oqmgr/qmgr_active.c +++ b/postfix/src/oqmgr/qmgr_active.c @@ -403,7 +403,7 @@ static void qmgr_active_done_2_generic(QMGR_MESSAGE *message) * daemon waits for the qmgr to accept the "new mail" trigger. */ if (message->flags) { - if (event_time() >= message->arrival_time.tv_sec + + if (event_time() >= message->create_time + (*message->sender ? var_max_queue_time : var_dsn_queue_time)) { msg_info("%s: from=<%s>, status=expired, returned to sender", message->queue_id, message->sender); @@ -498,8 +498,8 @@ static void qmgr_active_done_3_generic(QMGR_MESSAGE *message) * queue scans is finite. */ if (message->flags) { - if (message->arrival_time.tv_sec > 0) { - delay = event_time() - message->arrival_time.tv_sec; + if (message->create_time > 0) { + delay = event_time() - message->create_time; if (delay > var_max_backoff_time) delay = var_max_backoff_time; if (delay < var_min_backoff_time) diff --git a/postfix/src/oqmgr/qmgr_message.c b/postfix/src/oqmgr/qmgr_message.c index 5895b2e06..53c89cbb6 100644 --- a/postfix/src/oqmgr/qmgr_message.c +++ b/postfix/src/oqmgr/qmgr_message.c @@ -125,7 +125,7 @@ #include #include #include -#include +#include /* Client stubs. */ @@ -157,6 +157,7 @@ static QMGR_MESSAGE *qmgr_message_create(const char *queue_name, message->refcount = 0; message->single_rcpt = 0; message->arrival_time.tv_sec = message->arrival_time.tv_usec = 0; + message->create_time = 0; GETTIMEOFDAY(&message->active_time); message->data_offset = 0; message->queue_id = mystrdup(queue_id); @@ -387,7 +388,7 @@ static int qmgr_message_read(QMGR_MESSAGE *message) rec_type = REC_TYPE_ERROR; break; } - if ((n = dsn_attr_map(name)) != 0) { + if ((n = rec_attr_map(name)) != 0) { start = value; rec_type = n; } @@ -537,6 +538,11 @@ static int qmgr_message_read(QMGR_MESSAGE *message) REC_TYPE_TIME_SCAN(start, message->arrival_time); continue; } + if (rec_type == REC_TYPE_CTIME) { + if (message->create_time == 0) + message->create_time = atol(start); + continue; + } if (rec_type == REC_TYPE_FILT) { if (message->filter_xport != 0) myfree(message->filter_xport); @@ -706,6 +712,9 @@ static int qmgr_message_read(QMGR_MESSAGE *message) message->sasl_sender = mystrdup(""); if (message->rewrite_context == 0) message->rewrite_context = mystrdup(MAIL_ATTR_RWR_LOCAL); + /* Postfix < 2.3 compatibility. */ + if (message->create_time == 0) + message->create_time = message->arrival_time.tv_sec; /* * Clean up. diff --git a/postfix/src/pickup/Makefile.in b/postfix/src/pickup/Makefile.in index 8bcff5547..ca118fcf6 100644 --- a/postfix/src/pickup/Makefile.in +++ b/postfix/src/pickup/Makefile.in @@ -59,7 +59,6 @@ depend: $(MAKES) # do not edit below this line - it is generated by 'make depend' pickup.o: ../../include/attr.h pickup.o: ../../include/cleanup_user.h -pickup.o: ../../include/dsn_attr_map.h pickup.o: ../../include/input_transp.h pickup.o: ../../include/iostuff.h pickup.o: ../../include/lex_822.h @@ -72,6 +71,7 @@ pickup.o: ../../include/mail_queue.h pickup.o: ../../include/mail_server.h pickup.o: ../../include/msg.h pickup.o: ../../include/mymalloc.h +pickup.o: ../../include/rec_attr_map.h pickup.o: ../../include/rec_type.h pickup.o: ../../include/record.h pickup.o: ../../include/safe_open.h diff --git a/postfix/src/pickup/pickup.c b/postfix/src/pickup/pickup.c index e6fcb5c50..f36b57baa 100644 --- a/postfix/src/pickup/pickup.c +++ b/postfix/src/pickup/pickup.c @@ -140,7 +140,7 @@ #include #include #include -#include +#include /* Single-threaded server skeleton. */ @@ -211,9 +211,6 @@ static int copy_segment(VSTREAM *qfile, VSTREAM *cleanup, PICKUP_INFO *info, * mail system against unreasonable inputs. This also requires that we * limit the size of envelope records written by the local posting agent. * - * As time stamp we use the scrutinized queue file modification time, and - * ignore the time stamp embedded in the queue file. - * * Allow attribute records if the queue file is owned by the mail system * (postsuper -r) or if the attribute specifies the MIME body type * (sendmail -B). @@ -260,7 +257,7 @@ static int copy_segment(VSTREAM *qfile, VSTREAM *cleanup, PICKUP_INFO *info, saved_attr = mystrdup(vstring_str(buf)); skip_attr = (split_nameval(saved_attr, &attr_name, &attr_value) == 0 - && dsn_attr_map(attr_name) == 0); + && rec_attr_map(attr_name) == 0); myfree(saved_attr); /* Discard other/header/body action after "postsuper -r". */ if (skip_attr) diff --git a/postfix/src/postcat/Makefile.in b/postfix/src/postcat/Makefile.in index 4c18cd10d..04be39e01 100644 --- a/postfix/src/postcat/Makefile.in +++ b/postfix/src/postcat/Makefile.in @@ -57,13 +57,17 @@ depend: $(MAKES) @$(EXPORT) make -f Makefile.in Makefile 1>&2 # do not edit below this line - it is generated by 'make depend' +postcat.o: ../../include/attr.h +postcat.o: ../../include/iostuff.h postcat.o: ../../include/mail_conf.h postcat.o: ../../include/mail_params.h +postcat.o: ../../include/mail_proto.h postcat.o: ../../include/mail_queue.h postcat.o: ../../include/msg.h postcat.o: ../../include/msg_vstream.h postcat.o: ../../include/rec_type.h postcat.o: ../../include/record.h +postcat.o: ../../include/stringops.h postcat.o: ../../include/sys_defs.h postcat.o: ../../include/vbuf.h postcat.o: ../../include/vstream.h diff --git a/postfix/src/postcat/postcat.c b/postfix/src/postcat/postcat.c index f1389c595..c249bfae2 100644 --- a/postfix/src/postcat/postcat.c +++ b/postfix/src/postcat/postcat.c @@ -79,6 +79,7 @@ #include #include #include +#include /* Global library. */ @@ -87,6 +88,7 @@ #include #include #include +#include /* Application-specific. */ @@ -108,6 +110,9 @@ static void postcat(VSTREAM *fp, VSTRING *buffer, int flags) int ch; off_t offset; int in_message = 0; + const char *error_text; + char *attr_name; + char *attr_value; #define TEXT_RECORD(rec_type) \ (rec_type == REC_TYPE_CONT || rec_type == REC_TYPE_NORM) @@ -182,6 +187,20 @@ static void postcat(VSTREAM *fp, VSTRING *buffer, int flags) case REC_TYPE_END: vstream_printf("*** MESSAGE FILE END %s ***\n", VSTREAM_PATH(fp)); break; + case REC_TYPE_ATTR: + error_text = split_nameval(STR(buffer), &attr_name, &attr_value); + if (error_text != 0) { + msg_warn("%s: malformed attribute: %s: %.100s", + VSTREAM_PATH(fp), error_text, STR(buffer)); + break; + } + if (strcmp(attr_name, MAIL_ATTR_CREATE_TIME) == 0) { + time = atol(attr_value); + vstream_printf("%s: %s", MAIL_ATTR_CREATE_TIME, + asctime(localtime(&time))); + break; + } + /* FALLTHROUGH */ default: vstream_printf("%s: %s\n", rec_type_name(rec_type), STR(buffer)); break; diff --git a/postfix/src/postdrop/Makefile.in b/postfix/src/postdrop/Makefile.in index 7c1770eef..fead147a3 100644 --- a/postfix/src/postdrop/Makefile.in +++ b/postfix/src/postdrop/Makefile.in @@ -61,7 +61,6 @@ postdrop.o: ../../include/argv.h postdrop.o: ../../include/attr.h postdrop.o: ../../include/clean_env.h postdrop.o: ../../include/cleanup_user.h -postdrop.o: ../../include/dsn_attr_map.h postdrop.o: ../../include/iostuff.h postdrop.o: ../../include/mail_conf.h postdrop.o: ../../include/mail_params.h @@ -73,6 +72,7 @@ postdrop.o: ../../include/msg.h postdrop.o: ../../include/msg_syslog.h postdrop.o: ../../include/msg_vstream.h postdrop.o: ../../include/mymalloc.h +postdrop.o: ../../include/rec_attr_map.h postdrop.o: ../../include/rec_type.h postdrop.o: ../../include/record.h postdrop.o: ../../include/stringops.h diff --git a/postfix/src/postdrop/postdrop.c b/postfix/src/postdrop/postdrop.c index 488753f60..ee43bcd02 100644 --- a/postfix/src/postdrop/postdrop.c +++ b/postfix/src/postdrop/postdrop.c @@ -134,7 +134,7 @@ #include #include #include -#include +#include /* Application-specific. */ @@ -410,7 +410,7 @@ int main(int argc, char **argv) || STREQ(attr_value, MAIL_ATTR_ENC_NONE))) || STREQ(attr_name, MAIL_ATTR_DSN_ENVID) || STREQ(attr_name, MAIL_ATTR_DSN_NOTIFY) - || dsn_attr_map(attr_name) + || rec_attr_map(attr_name) || (STREQ(attr_name, MAIL_ATTR_RWR_CONTEXT) && (STREQ(attr_value, MAIL_ATTR_RWR_LOCAL) || STREQ(attr_value, MAIL_ATTR_RWR_REMOTE))) diff --git a/postfix/src/qmgr/Makefile.in b/postfix/src/qmgr/Makefile.in index 8faf4e80a..e00895342 100644 --- a/postfix/src/qmgr/Makefile.in +++ b/postfix/src/qmgr/Makefile.in @@ -214,7 +214,6 @@ qmgr_message.o: ../../include/deliver_completed.h qmgr_message.o: ../../include/deliver_request.h qmgr_message.o: ../../include/dict.h qmgr_message.o: ../../include/dsn.h -qmgr_message.o: ../../include/dsn_attr_map.h qmgr_message.o: ../../include/dsn_buf.h qmgr_message.o: ../../include/dsn_mask.h qmgr_message.o: ../../include/iostuff.h @@ -227,6 +226,7 @@ qmgr_message.o: ../../include/myflock.h qmgr_message.o: ../../include/mymalloc.h qmgr_message.o: ../../include/opened.h qmgr_message.o: ../../include/qmgr_user.h +qmgr_message.o: ../../include/rec_attr_map.h qmgr_message.o: ../../include/rec_type.h qmgr_message.o: ../../include/recipient_list.h qmgr_message.o: ../../include/record.h diff --git a/postfix/src/qmgr/qmgr.h b/postfix/src/qmgr/qmgr.h index 83be8073e..cffdc180c 100644 --- a/postfix/src/qmgr/qmgr.h +++ b/postfix/src/qmgr/qmgr.h @@ -247,7 +247,8 @@ struct QMGR_MESSAGE { VSTREAM *fp; /* open queue file or null */ int refcount; /* queue entries */ int single_rcpt; /* send one rcpt at a time */ - struct timeval arrival_time; /* time when queued */ + struct timeval arrival_time; /* start of receive transaction */ + time_t create_time; /* queue file create time */ struct timeval active_time; /* time of entry into active queue */ time_t queued_time; /* sanitized time when moved to the * active queue */ diff --git a/postfix/src/qmgr/qmgr_active.c b/postfix/src/qmgr/qmgr_active.c index b2136b1e9..67320c570 100644 --- a/postfix/src/qmgr/qmgr_active.c +++ b/postfix/src/qmgr/qmgr_active.c @@ -403,7 +403,7 @@ static void qmgr_active_done_2_generic(QMGR_MESSAGE *message) * daemon waits for the qmgr to accept the "new mail" trigger. */ if (message->flags) { - if (event_time() >= message->arrival_time.tv_sec + + if (event_time() >= message->create_time + (*message->sender ? var_max_queue_time : var_dsn_queue_time)) { msg_info("%s: from=<%s>, status=expired, returned to sender", message->queue_id, message->sender); @@ -498,8 +498,8 @@ static void qmgr_active_done_3_generic(QMGR_MESSAGE *message) * queue scans is finite. */ if (message->flags) { - if (message->arrival_time.tv_sec > 0) { - delay = event_time() - message->arrival_time.tv_sec; + if (message->create_time > 0) { + delay = event_time() - message->create_time; if (delay > var_max_backoff_time) delay = var_max_backoff_time; if (delay < var_min_backoff_time) diff --git a/postfix/src/qmgr/qmgr_message.c b/postfix/src/qmgr/qmgr_message.c index 29e43f9aa..778540a01 100644 --- a/postfix/src/qmgr/qmgr_message.c +++ b/postfix/src/qmgr/qmgr_message.c @@ -134,7 +134,7 @@ #include #include #include -#include +#include /* Client stubs. */ @@ -166,6 +166,7 @@ static QMGR_MESSAGE *qmgr_message_create(const char *queue_name, message->refcount = 0; message->single_rcpt = 0; message->arrival_time.tv_sec = message->arrival_time.tv_usec = 0; + message->create_time = 0; GETTIMEOFDAY(&message->active_time); message->queued_time = sane_time(); message->data_offset = 0; @@ -419,7 +420,7 @@ static int qmgr_message_read(QMGR_MESSAGE *message) rec_type = REC_TYPE_ERROR; break; } - if ((n = dsn_attr_map(name)) != 0) { + if ((n = rec_attr_map(name)) != 0) { start = value; rec_type = n; } @@ -570,6 +571,11 @@ static int qmgr_message_read(QMGR_MESSAGE *message) REC_TYPE_TIME_SCAN(start, message->arrival_time); continue; } + if (rec_type == REC_TYPE_CTIME) { + if (message->create_time == 0) + message->create_time = atol(start); + continue; + } if (rec_type == REC_TYPE_FILT) { if (message->filter_xport != 0) myfree(message->filter_xport); @@ -739,6 +745,9 @@ static int qmgr_message_read(QMGR_MESSAGE *message) message->sasl_sender = mystrdup(""); if (message->rewrite_context == 0) message->rewrite_context = mystrdup(MAIL_ATTR_RWR_LOCAL); + /* Postfix < 2.3 compatibility. */ + if (message->create_time == 0) + message->create_time = message->arrival_time.tv_sec; /* * Clean up. diff --git a/postfix/src/smtpd/smtpd.c b/postfix/src/smtpd/smtpd.c index 46811f889..d25a60121 100644 --- a/postfix/src/smtpd/smtpd.c +++ b/postfix/src/smtpd/smtpd.c @@ -1989,7 +1989,7 @@ static int rcpt_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *argv) * XXX We use REC_TYPE_ATTR for DSN-related recipient attributes even though * 1) REC_TYPE_ATTR is not meant for multiple instances of the same named * attribute, and 2) mixing REC_TYPE_ATTR with REC_TYPE_(not attr) - * requires that we map attributes with dsn_attr_map() in order to + * requires that we map attributes with rec_attr_map() in order to * simplify the recipient record processing loops in the cleanup and qmgr * servers. *