diff --git a/postfix/HISTORY b/postfix/HISTORY index b7972bc49..1ad04048e 100644 --- a/postfix/HISTORY +++ b/postfix/HISTORY @@ -5485,28 +5485,30 @@ Apologies for any names omitted. 20011008 Bugfix: there was a minute memory leak when an smtpd access - restriction is misconfigured. File: smtpd/smtpd_check.c. + restriction was misconfigured. File: smtpd/smtpd_check.c. 20011010 - Postfix daemons now print the name of the UNIX-domain socket - (instead of "unknown stream") complaining about a malformed - client request. Files: master/*server.c. + Code cleanup: Postfix daemons now print the name of the + UNIX-domain socket (instead of "unknown stream") in case + of a malformed client request. Files: master/*server.c. 20011010-14 - Replaced the ugly mail_print() and mail-scan() protocols - by (name,value) attribute lists. This gives better error - detection when we start making changes to internal protocols, + Code cleanup: replaced the ugly mail_print() and mail-scan() + protocols by (name,value) attribute lists. This gives better + error detection when we make changes to internal protocols, and allows new attributes to be introduced without breaking - everything immediately. + everything immediately. Files: util/attr_print.c util/attr_scan.c + global/mail_command_server.c global/mail_command_client.c + as wel as most Postfix applications and daemons. 20011015 Put base 64 encoding into place on the replaced internal protocols. Files: util/base64_code.[hc]. - Feature: header/body REJECT rules can now end in text that + Feature: header/body REJECT rules can now provide text that is sent to the originator. Files: cleanup/cleanup.c, cleanup/cleanup_message.c, conf/sample-filter.cf. @@ -5542,17 +5544,29 @@ Apologies for any names omitted. util/attr_scan.c. Bugfix: qmqpd could read past the end of a string while - looking for the VERP magic token in the envelope sender + looking for qmail's VERP magic token in the envelope sender address. File: qmqpd/qmqpd.c. + Code cleanup: finished testing the new internal protocols. + The only bug was with the flush server, which still needs + to support the old (string + null byte) protocol for triggers + from the Postfix master daemon. + +20011103 + + Bugfix: Postfix would log the wrong error text when locally + submitted mail was deferred due to "soft_bounce = yes". + + Bugfix: The LDAP client dropped any entries that don't have + the result_attribute, but errored out when a DN didn't + exist. The behavior is now consistent: treat non-existant + DN's in a special result attribute expansion the same as + DN's with no attribtue. LaMont Jones, HP. + Open problems: - Medium: need in-process caching for map lookups. - - Low: The $process_id_directory setting is not used anywhere - in Postfix. Problem reported by Michael Smith, texas.net. - This should either be documented, or better, the code should - warn about attempts to set a read-only parameter. + Medium: need in-process caching for map lookups. LDAP + servers seem to need this in particular. Medium: make address rewriting on/off configurable for envelopes and/or headers. @@ -5560,5 +5574,12 @@ Open problems: Medium: smtpd access maps don't understand the recipient delimiter setting. + Low: The $process_id_directory setting is not used anywhere + in Postfix. Problem reported by Michael Smith, texas.net. + This should be documented, or better, the code should warn + about attempts to set read-only parameters. + Low: the virtual delivery agent needs a way to specify fixed uid/gid for all deliveries. + + Low: postconf -e edits parameters that postconf won't list. diff --git a/postfix/RELEASE_NOTES b/postfix/RELEASE_NOTES index d28737876..d4fae5c2e 100644 --- a/postfix/RELEASE_NOTES +++ b/postfix/RELEASE_NOTES @@ -1,9 +1,9 @@ -This release introduces a negligible amount of features and is all -about revision of Postfix internals. With more than 70 pages of -context diffs compared to the previous snapshot, this release is -a baseline for upcoming feature changes. +Snapshot 20011103 introduces a negligible amount of features and +is all about revision of Postfix internals. With more than 70 pages +of context diffs compared to the previous snapshot, this release +is a baseline for upcoming feature changes. -Major changes with snapshot-20011102 +Major changes with snapshot-20011103 ==================================== The protocol between Postfix daemons was replaced by something that @@ -12,8 +12,8 @@ that can also be used to talk to non-Postfix programs. The format of the protocols is described in src/util/attr_scan.c. In header/body_check files, REJECT can now be followed by text that -is sent to the originator. That feature was stuck waiting for the -internal protocol revision. +is sent to the originator. That feature was stuck waiting for years, +pending the internal protocol revision. Incompatible changes with snapshot-20011008 =========================================== @@ -82,8 +82,10 @@ before accepting a message. This delay gives Postfix a chance catch up and access the disk, while still allowing new mail to arrive. -This feature is disabled by default, because it needs further -development. It will change but I have not enough time now. +This feature is on by default, but currently it has effect only +when mail arrives via a relatively small number of SMTP clients. +The code needs further development. It will change but I have not +enough time now. The in_flow_delay feature has effect mainly when your system is being flooded through a limited number of SMTP connections. This diff --git a/postfix/makedefs b/postfix/makedefs index 831e8ccd5..2c9a7f27e 100644 --- a/postfix/makedefs +++ b/postfix/makedefs @@ -230,11 +230,17 @@ ReliantUNIX-?.5.43) SYSTYPE=ReliantUnix543 RANLIB=echo SYSLIBS="-lresolv -lsocket -lnsl" ;; -Rhapsody.5*|Darwin.1.*) +Rhapsody.5*|Darwin.*) SYSTYPE=RHAPSODY5 # Use the native compiler by default : ${CC=cc} AWK=gawk + case $RELEASE in + 1.[0-3]) ;; + *) AWK=awk + SYSLIBS=-flat_namespace + ;; + esac ;; "Mac OS".10*) SYSTYPE=MACOSX # Use the native compiler by default diff --git a/postfix/src/cleanup/cleanup_api.c b/postfix/src/cleanup/cleanup_api.c index b2e88eb2a..846761b33 100644 --- a/postfix/src/cleanup/cleanup_api.c +++ b/postfix/src/cleanup/cleanup_api.c @@ -238,9 +238,10 @@ int cleanup_flush(CLEANUP_STATE *state) state->queue_id, state->sender) == 0) { state->errs = 0; } else { - if (var_soft_bounce == 0) + if (var_soft_bounce == 0) { msg_warn("%s: bounce message failure", state->queue_id); - state->errs = CLEANUP_STAT_WRITE; + state->errs = CLEANUP_STAT_WRITE; + } } } if (REMOVE(cleanup_path)) diff --git a/postfix/src/flush/flush.c b/postfix/src/flush/flush.c index 9e3499cd0..67a8814c8 100644 --- a/postfix/src/flush/flush.c +++ b/postfix/src/flush/flush.c @@ -511,6 +511,51 @@ static int flush_refresh_service(int max_age) return (FLUSH_STAT_OK); } +/* flush_request_receive - receive request */ + +static int flush_request_receive(VSTREAM *client_stream, VSTRING *request) +{ + int count; + + /* + * Kluge: choose the protocol depending on the request size. + */ + if (read_wait(vstream_fileno(client_stream), var_ipc_timeout) < 0) { + msg_warn("timeout while waiting for data from %s", + VSTREAM_PATH(client_stream)); + return (-1); + } + if ((count = peekfd(vstream_fileno(client_stream))) < 0) { + msg_warn("cannot examine read buffer of %s: %m", + VSTREAM_PATH(client_stream)); + return (-1); + } + + /* + * Short request: master trigger. Use the string+null protocol. + */ + if (count <= 2) { + if (vstring_get_null(request, client_stream) == VSTREAM_EOF) { + msg_warn("end-of-input while reading request from %s: %m", + VSTREAM_PATH(client_stream)); + return (-1); + } + } + + /* + * Long request: real flush client. Use the attribute list protocol. + */ + else { + if (attr_scan(client_stream, + ATTR_FLAG_MORE | ATTR_FLAG_STRICT, + ATTR_TYPE_STR, MAIL_ATTR_REQ, request, + ATTR_TYPE_END) != 1) { + return (-1); + } + } + return (0); +} + /* flush_service - perform service for client */ static void flush_service(VSTREAM *client_stream, char *unused_service, @@ -540,12 +585,7 @@ static void flush_service(VSTREAM *client_stream, char *unused_service, * All connection-management stuff is handled by the common code in * single_server.c. */ - if (peekfd(vstream_fileno(client_stream)) <= 2 ? - (vstring_get_null(request, client_stream) != VSTREAM_EOF) : - (attr_scan(client_stream, - ATTR_FLAG_MORE | ATTR_FLAG_STRICT, - ATTR_TYPE_STR, MAIL_ATTR_REQ, request, - ATTR_TYPE_END) == 1)) { + if (flush_request_receive(client_stream, request) == 0) { if (STREQ(STR(request), FLUSH_REQ_ADD)) { site = vstring_alloc(10); queue_id = vstring_alloc(10); diff --git a/postfix/src/global/mail_version.h b/postfix/src/global/mail_version.h index 34e4646f8..aa7b9f1f1 100644 --- a/postfix/src/global/mail_version.h +++ b/postfix/src/global/mail_version.h @@ -15,7 +15,7 @@ * Version of this program. */ #define VAR_MAIL_VERSION "mail_version" -#define DEF_MAIL_VERSION "Snapshot-20011102" +#define DEF_MAIL_VERSION "Snapshot-20011103" extern char *var_mail_version; /* LICENSE diff --git a/postfix/src/util/attr_scan.c b/postfix/src/util/attr_scan.c index 2f6267b99..afcf3c99c 100644 --- a/postfix/src/util/attr_scan.c +++ b/postfix/src/util/attr_scan.c @@ -43,7 +43,7 @@ /* .in /* /* All attribute names and attribute values are sent as base64-encoded -/* strings. Each base64-encoded must be no longer than 2*var_line_limit +/* strings. Each base64 encoding must be no longer than 2*var_line_limit /* characters. The formatting rules aim to make implementations in PERL /* and other languages easy. /* @@ -93,7 +93,9 @@ /* This argument is followed by an attribute name and a VSTRING pointer. /* .IP "ATTR_TYPE_HASH (HTABLE *)" /* All further input attributes are processed as string attributes. -/* In this case, no specific attribute sequence is enforced. +/* No specific attribute sequence is enforced. +/* All attributes up to the attribute list terminator are read, +/* but only the first instance of each attribute is stored. /* .sp /* The attribute string values are stored in the hash table under /* keys equal to the attribute name (obtained from the input stream). @@ -105,14 +107,14 @@ /* This argument terminates the requested attribute list. /* .RE /* BUGS -/* ATTR_TYPE_HASH accepts attributes with arbitrary names from an -/* untrusted source. This is safe only if the resulting table is +/* ATTR_TYPE_HASH accepts attributes with arbitrary names from possibly +/* untrusted sources. This is unsafe, unless the resulting table is /* queried only with known to be good attribute names. /* DIAGNOSTICS /* attr_scan() and attr_vscan() return -1 when malformed input is /* detected (string too long, incomplete line, missing end marker). -/* Otherwise, the result value is the number of attributes that were -/* successfully recovered from the input stream (a hash table counts +/* Otherwise, the result value is the number of attributes that were +/* successfully recovered from the input stream (a hash table counts /* as the number of entries stored into the table). /* /* Panic: interface violation. All system call errors are fatal. @@ -198,7 +200,7 @@ static int attr_scan_number(VSTREAM *fp, unsigned *ptr, VSTRING *str_buf, if ((ch = attr_scan_string(fp, str_buf, context)) < 0) return (-1); if (sscanf(STR(str_buf), "%u%c", ptr, &junk) != 1 || junk != 0) { - msg_warn("malformed numerical data from %s while %s: %.100s", + msg_warn("malformed numerical data from %s while reading %s: %.100s", VSTREAM_PATH(fp), context, STR(str_buf)); return (-1); } @@ -253,7 +255,7 @@ int attr_vscan(VSTREAM *fp, int flags, va_list ap) if (wanted_type == ATTR_TYPE_END) { if ((flags & ATTR_FLAG_MORE) != 0) return (conversions); - wanted_name = "list terminator"; + wanted_name = "(list terminator)"; } else if (wanted_type == ATTR_TYPE_HASH) { wanted_name = "(any attribute name or list terminator)"; hash_table = va_arg(ap, HTABLE *); @@ -343,8 +345,8 @@ int attr_vscan(VSTREAM *fp, int flags, va_list ap) return (-1); } string = va_arg(ap, VSTRING *); - if ((ch = attr_scan_string(fp, string, - "input attribute value")) < 0) + if ((ch = attr_scan_string(fp, string, + "input attribute value")) < 0) return (-1); if (ch != '\n') { msg_warn("multiple values for attribute %s from %s", @@ -358,8 +360,8 @@ int attr_vscan(VSTREAM *fp, int flags, va_list ap) STR(name_buf), VSTREAM_PATH(fp)); return (-1); } - if ((ch = attr_scan_string(fp, str_buf, -"input attribute value")) < 0) + if ((ch = attr_scan_string(fp, str_buf, + "input attribute value")) < 0) return (-1); if (ch != '\n') { msg_warn("multiple values for attribute %s from %s", diff --git a/postfix/src/util/attr_scan.ref b/postfix/src/util/attr_scan.ref index fb02bd5e2..cd06a27d8 100644 --- a/postfix/src/util/attr_scan.ref +++ b/postfix/src/util/attr_scan.ref @@ -9,13 +9,13 @@ ./attr_scan: input attribute value: 4711 ./attr_scan: unknown_stream: wanted attribute: string ./attr_scan: input attribute name: string -./attr_scan: attribute value: whoopee +./attr_scan: input attribute value: whoopee ./attr_scan: unknown_stream: wanted attribute: (any attribute name or list terminator) ./attr_scan: input attribute name: foo-name -./attr_scan: attribute value: foo-value +./attr_scan: input attribute value: foo-value ./attr_scan: unknown_stream: wanted attribute: (any attribute name or list terminator) ./attr_scan: input attribute name: bar-name -./attr_scan: attribute value: bar-value +./attr_scan: input attribute value: bar-value ./attr_scan: unknown_stream: wanted attribute: (any attribute name or list terminator) ./attr_scan: input attribute name: (end) ./attr_scan: unknown_stream: wanted attribute: number @@ -23,8 +23,8 @@ ./attr_scan: input attribute value: 4711 ./attr_scan: unknown_stream: wanted attribute: string ./attr_scan: input attribute name: string -./attr_scan: attribute value: whoopee -./attr_scan: unknown_stream: wanted attribute: list terminator +./attr_scan: input attribute value: whoopee +./attr_scan: unknown_stream: wanted attribute: (list terminator) ./attr_scan: input attribute name: (end) number 4711 string whoopee diff --git a/postfix/src/util/base64_code.c b/postfix/src/util/base64_code.c index 469b1c0fa..1851b3d31 100644 --- a/postfix/src/util/base64_code.c +++ b/postfix/src/util/base64_code.c @@ -93,7 +93,7 @@ VSTRING *base64_encode(VSTRING *result, const char *in, int len) VSTRING *base64_decode(VSTRING *result, const char *in, int len) { - static char *un_b64 = 0; + static unsigned char *un_b64 = 0; const unsigned char *cp; int count; int ch0; @@ -114,7 +114,7 @@ VSTRING *base64_decode(VSTRING *result, const char *in, int len) * Once: initialize the decoding lookup table on the fly. */ if (un_b64 == 0) { - un_b64 = mymalloc(CHARS_PER_BYTE); + un_b64 = (unsigned char *) mymalloc(CHARS_PER_BYTE); memset(un_b64, INVALID, CHARS_PER_BYTE); for (cp = to_b64; cp < to_b64 + sizeof(to_b64); cp++) un_b64[*cp] = cp - to_b64; diff --git a/postfix/src/util/dict_ldap.c b/postfix/src/util/dict_ldap.c index 528769248..ebbfe8f90 100644 --- a/postfix/src/util/dict_ldap.c +++ b/postfix/src/util/dict_ldap.c @@ -373,13 +373,24 @@ static void dict_ldap_get_values(DICT_LDAP *dict_ldap, LDAPMessage * res, dict_ldap->result_attributes->argv, 0, &tv, &resloop); } - if (rc == LDAP_SUCCESS) - dict_ldap_get_values(dict_ldap, resloop, result); - else { - msg_warn("%s: search error %d: %s ", myname, rc, + switch (rc) { + case LDAP_SUCCESS: + dict_ldap_get_values(dict_ldap, resloop, result); + break; + case LDAP_NO_SUCH_OBJECT: + /* Go ahead and treat this as though the DN existed + * and just didn't have any result attributes. + */ + msg_warn("%s: DN %s not found, skipping ", myname, + vals[i]); + break; + default: + msg_warn("%s: search error %d: %s ", myname, rc, ldap_err2string(rc)); - dict_errno = DICT_ERR_RETRY; + dict_errno = DICT_ERR_RETRY; + break; } + if (resloop != 0) ldap_msgfree(resloop); }