# Localize these
INSPECT_DIR=/var/spool/filter
- SENDMAIL=/usr/sbin/sendmail
+ SENDMAIL="/usr/sbin/sendmail -i"
# Exit codes from <sysexits.h>
EX_TEMPFAIL=75
above bug could cause an address to grow exponentially in
size. Problem reported by Victor Duchovni, Morgan Stanley.
File: global/split_addr.c.
+
+20010918
+
+ Bugfix: the mail_addr_map() fix was almost but not quite
+ right. It took two clever people and several iterations of
+ email to really fix the mail_addr_map() problem. Thanks
+ to Victor Duchovni and Liviu Daia.
+
+20011016
+
+ Bugfix: As of 20000625, Errors-To: was broken, because the
+ code to extract the address was not moved from recipient
+ address rewriting to sender address rewriting. Problem
+ reported by Roelof Osinga @ nisser.com. File:
+ cleanup/cleanup_message.c.
+
+20011023
+
+ Bugfix: the FILTER_README content filtering example had
+ not been updated to include the sendmail "-i" command line
+ option.
+
+20011029
+
+ Bugfix: virtual map expansion terminated early because the
+ detection of self-referential entries was flawed. File:
+ cleanup/cleanup_map1n.c.
+
+20011031
+
+ Bugfix: mail_date() mis-formatted negative time zone offsets
+ with fractional hours (-03-30 instead of -0330). Fix by
+ Chad House, greyfirst.ca. File: global/mail_date.c.
+
+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 attribute. LaMont Jones, HP.
That's seven backslashes :-) But at least this works with sh and csh.
+In order to build Postfix for very large applications, where you
+expect to run more than 1000 delivery processes, you may need to
+override the definition of the FD_SETSIZE macro to make select()
+work correctly:
+
+ % make makefiles CCARGS=-DFD_SETSIZE=2048
+
In any case, if the command
% make
state->queue_id, state->sender) == 0) {
state->errs = 0;
} else {
- msg_warn("%s: bounce message failure", state->queue_id);
- state->errs = CLEANUP_STAT_WRITE;
+ if (var_soft_bounce == 0) {
+ msg_warn("%s: bounce message failure", state->queue_id);
+ state->errs = CLEANUP_STAT_WRITE;
+ }
}
}
if (REMOVE(cleanup_path))
break;
}
for (count = 0; /* void */ ; count++) {
- if (been_here_fixed(been_here, argv->argv[arg]) != 0)
+
+ /*
+ * Don't expand an address that already expanded into itself.
+ */
+ if (been_here_check_fixed(been_here, argv->argv[arg]) != 0)
break;
if (count >= MAX_RECURSION) {
msg_warn("%s: unreasonable %s map nesting for %s",
argv_add(argv, STR(state->temp1), ARGV_END);
argv_terminate(argv);
}
+
+ /*
+ * Allow an address to expand into itself once.
+ */
+ if (strcasecmp(saved_lhs, STR(state->temp1)) == 0)
+ been_here_fixed(been_here, saved_lhs);
}
myfree(saved_lhs);
argv_free(lookup);
if (hdr_opts->type == HDR_RESENT_FROM && state->resent_from == 0)
state->resent_from =
cleanup_extract_internal(state->header_buf, *tpp);
+ if (hdr_opts->type == HDR_RETURN_RECEIPT_TO && !state->return_receipt)
+ state->return_receipt =
+ cleanup_extract_internal(state->header_buf, *tpp);
+ if (hdr_opts->type == HDR_ERRORS_TO && !state->errors_to)
+ state->errors_to =
+ cleanup_extract_internal(state->header_buf, *tpp);
}
vstring_sprintf(state->header_buf, "%s: ", hdr_opts->name);
tok822_externalize(state->header_buf, tree, TOK822_STR_HEAD);
}
if (cleanup_masq_domains)
cleanup_masquerade_tree(*tpp, cleanup_masq_domains);
- if (hdr_opts->type == HDR_RETURN_RECEIPT_TO && !state->return_receipt)
- state->return_receipt =
- cleanup_extract_internal(state->header_buf, *tpp);
- if (hdr_opts->type == HDR_ERRORS_TO && !state->errors_to)
- state->errors_to =
- cleanup_extract_internal(state->header_buf, *tpp);
}
vstring_sprintf(state->header_buf, "%s: ", hdr_opts->name);
tok822_externalize(state->header_buf, tree, TOK822_STR_HEAD);
/* Application-specific. */
#define STR vstring_str
+#define LEN VSTRING_LEN
/* mail_addr_map - map a canonical address */
if ((string = mail_addr_find(path, address, &extension)) != 0) {
/*
- * Prepend the original user to @otherdomain.
+ * Prepend the original user to @otherdomain, but do not propagate
+ * the unmatched address extension.
*/
if (*string == '@') {
buffer = vstring_alloc(100);
vstring_strncpy(buffer, address, ratsign - address);
else
vstring_strcpy(buffer, address);
+ if (extension)
+ vstring_truncate(buffer, LEN(buffer) - strlen(extension));
vstring_strcat(buffer, string);
string = STR(buffer);
-
- /*
- * The above code copies the address, including address
- * extension, to the result. Discard the address extension at
- * this point, to prevent a second address extension copy by
- * mail_addr_crunch() below. Fix by Victor Duchovni, Morgan
- * Stanley.
- *
- * In combination with an obscure bug in the split_addr() routine
- * that mis-parsed an address without information before the
- * extension, this could result in the exponential growth of the
- * size of an address. Problem reported by Victor Duchovni,
- * Morgan Stanley.
- */
- if (extension) {
- myfree(extension);
- extension = 0;
- }
}
/*
/*
* Initialize.
*/
+#define UPDATE(dst, src) { myfree(dst); dst = mystrdup(src); }
+
mail_conf_read();
msg_verbose = 1;
- var_rcpt_delim = "+";
if (chdir(var_queue_dir) < 0)
msg_fatal("chdir %s: %m", var_queue_dir);
path = maps_create(argv[0], argv[1], DICT_FLAG_LOCK);
while (vstring_fgets_nonl(buffer, VSTREAM_IN)) {
+ msg_info("=== Address extension on, extension propagation on ===");
+ UPDATE(var_rcpt_delim, "+");
+ if ((result = mail_addr_map(path, STR(buffer), 1)) != 0)
+ argv_free(result);
+ msg_info("=== Address extension on, extension propagation off ===");
+ if ((result = mail_addr_map(path, STR(buffer), 0)) != 0)
+ argv_free(result);
+ msg_info("=== Address extension off ===");
+ UPDATE(var_rcpt_delim, "");
if ((result = mail_addr_map(path, STR(buffer), 1)) != 0)
argv_free(result);
}
if (gmtoff < -DAY_MIN || gmtoff > DAY_MIN)
msg_panic("UTC time offset %d is larger than one day", gmtoff);
vstring_sprintf_append(vp, "%+03d%02d", (int) (gmtoff / HOUR_MIN),
- (int) (gmtoff % HOUR_MIN));
+ (int) (abs(gmtoff) % HOUR_MIN));
/*
* Finally, add the time zone name.
* Version of this program.
*/
#define VAR_MAIL_VERSION "mail_version"
-#define DEF_MAIL_VERSION "Postfix-20010228-pl05"
+#define DEF_MAIL_VERSION "Postfix-20010228-pl06"
extern char *var_mail_version;
/* LICENSE
/*
* Backwards compatibility: don't split owner-foo or foo-request.
*/
- if (var_ownreq_special != 0) {
+ if (delimiter == '-' && var_ownreq_special != 0) {
if (strncasecmp(localpart, "owner-", 6) == 0)
return (0);
if ((len = strlen(localpart) - 8) > 0
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);
}