than a year until I found out how to reproduce it. File:
util/vstream.c.
+20030105
+
+ Cleanup: removed the address syntax check from the queue
+ manager, since a better test was implemented recently in
+ the trivial-rewrite server. Files: *qmgr/qmgr_message.c.
+
+ Bugfix: redirect bounce/defer to the address verification
+ service where appropriate. Files: *qmgr/qmgr_bounce.c,
+ *qmgr/qmgr_defer.c.
+
+ Bugfix: "no such file or directory" warnings after "postfix
+ reload" when a chrooted smtpd reconnects to the proxy
+ service. Fix: use "private/proxymap" if possible, otherwise
+ use "$queue_dir/private/proxymap". File: global/dict_proxy.c.
+
+ Robustness: daemons now chdir() to the queue directory before
+ running the pre-jail initialization code, so that daemons
+ running in stand-alone mode produce more consistent results.
+ Files: master/single_server.c, master/multi_server.c.
+ master/trigger_server.c.
+
+ Bugfix: "sendmail -bs" tried to access the proxymap service.
+ It should not try to open any user/domain/uce related tables
+ at all. File: smtpd/smtpd.c.
+
Open problems:
Med: do not postpone rejected "MAIL FROM" size information,
* XXX Use absolute pathname to make this work from non-daemon processes.
*/
if (proxy_stream == 0) {
- if (access(var_queue_dir, F_OK) == 0)
+ if (access(MAIL_CLASS_PRIVATE "/" MAIL_SERVICE_PROXYMAP, F_OK) == 0)
+ prefix = MAIL_CLASS_PRIVATE;
+ else
prefix = kludge = concatenate(var_queue_dir, "/",
MAIL_CLASS_PRIVATE, (char *) 0);
- else
- prefix = MAIL_CLASS_PRIVATE;
proxy_stream = clnt_stream_create(prefix,
MAIL_SERVICE_PROXYMAP,
var_ipc_idle_limit,
* Patches change the patchlevel and the release date. Snapshots change the
* release date only, unless they include the same bugfix as a patch release.
*/
-#define MAIL_RELEASE_DATE "20030105"
+#define MAIL_RELEASE_DATE "20030106"
#define VAR_MAIL_VERSION "mail_version"
#define DEF_MAIL_VERSION "2.0.0-" MAIL_RELEASE_DATE
/*
* Run pre-jail initialization.
*/
+ if (chdir(var_queue_dir) < 0)
+ msg_fatal("chdir(\"%s\"): %m", var_queue_dir);
if (pre_init)
pre_init(multi_server_name, multi_server_argv);
/*
* Optionally, restrict the damage that this process can do.
*/
- if (chdir(var_queue_dir) < 0)
- msg_fatal("chdir(\"%s\"): %m", var_queue_dir);
resolve_local_init();
chroot_uid(root_dir, user_name);
/*
* Run pre-jail initialization.
*/
+ if (chdir(var_queue_dir) < 0)
+ msg_fatal("chdir(\"%s\"): %m", var_queue_dir);
if (pre_init)
pre_init(single_server_name, single_server_argv);
/*
* Optionally, restrict the damage that this process can do.
*/
- if (chdir(var_queue_dir) < 0)
- msg_fatal("chdir(\"%s\"): %m", var_queue_dir);
resolve_local_init();
chroot_uid(root_dir, user_name);
/*
* Run pre-jail initialization.
*/
+ if (chdir(var_queue_dir) < 0)
+ msg_fatal("chdir(\"%s\"): %m", var_queue_dir);
if (pre_init)
pre_init(trigger_server_name, trigger_server_argv);
/*
* Optionally, restrict the damage that this process can do.
*/
- if (chdir(var_queue_dir) < 0)
- msg_fatal("chdir(\"%s\"): %m", var_queue_dir);
resolve_local_init();
chroot_uid(root_dir, user_name);
int status;
va_start(ap, format);
- status = vbounce_append(BOUNCE_FLAG_KEEP, message->queue_id,
+ status = vbounce_append(message->tflags, message->queue_id,
recipient->orig_rcpt, recipient->address, "none",
message->arrival_time, format, ap);
va_end(ap);
/*
* Update the message structure and log the message disposition.
*/
- message->flags |= defer_append(BOUNCE_FLAG_KEEP, message->queue_id,
+ message->flags |= defer_append(message->tflags, message->queue_id,
recipient->orig_rcpt, recipient->address,
"none", message->arrival_time, "%s", reason);
}
resolve_clnt_init(&reply);
for (recipient = list.info; recipient < list.info + list.len; recipient++) {
- /*
- * This may be a bit late in the game, but it is the most convenient
- * place to scrutinize the destination address syntax. We have a
- * complete queue file, so bouncing is easy. That luxury is not
- * available to the cleanup service. The main issue is that we want
- * to have this test in one place, instead of having to do this in
- * every front-ent program.
- */
- if ((at = strrchr(recipient->address, '@')) != 0
- && (at + 1)[strspn(at + 1, "[]0123456789.")] != 0
- && valid_hostname(at + 1, DONT_GRIPE) == 0) {
- qmgr_bounce_recipient(message, recipient,
- "bad host/domain syntax: \"%s\"", at + 1);
- continue;
- }
-
/*
* Resolve the destination to (transport, nexthop, address). The
* result address may differ from the one specified by the sender.
/* proxy_map_find - look up or open table */
-static DICT *proxy_map_find(const char *map_type_name, int request_flags)
+static DICT *proxy_map_find(const char *map_type_name, int request_flags,
+ int *statp)
{
DICT *dict;
* Canonicalize the map name. If the map is not on the approved list,
* deny the request.
*/
+#define PROXY_MAP_FIND_ERROR_RETURN(x) { *statp = (x); return (0); }
+
while (strncmp(map_type_name, PROXY_COLON, PROXY_COLON_LEN) == 0)
map_type_name += PROXY_COLON_LEN;
+ if (strchr(map_type_name, ':') == 0)
+ PROXY_MAP_FIND_ERROR_RETURN(PROXY_STAT_BAD);
if (htable_locate(proxy_read_maps, map_type_name) == 0) {
msg_warn("request for unapproved table: \"%s\"", map_type_name);
msg_warn("to approve a table for %s access, specify it in %s with %s",
MAIL_SERVICE_PROXYMAP, MAIN_CONF_FILE, VAR_PROXY_READ_MAPS);
- return (0);
+ PROXY_MAP_FIND_ERROR_RETURN(PROXY_STAT_DENY);
}
/*
ATTR_TYPE_END) != 3) {
reply_status = PROXY_STAT_BAD;
reply_value = "";
- } else if ((dict = proxy_map_find(STR(request_map), request_flags)) == 0) {
- reply_status = PROXY_STAT_DENY;
+ } else if ((dict = proxy_map_find(STR(request_map), request_flags,
+ &reply_status)) == 0) {
reply_value = "";
} else if ((reply_value = dict_get(dict, STR(request_key))) != 0) {
reply_status = PROXY_STAT_OK;
ATTR_TYPE_END) != 2) {
reply_status = PROXY_STAT_BAD;
reply_flags = 0;
- } else if ((dict = proxy_map_find(STR(request_map), request_flags)) == 0) {
- reply_status = PROXY_STAT_DENY;
+ } else if ((dict = proxy_map_find(STR(request_map), request_flags,
+ &reply_status)) == 0) {
reply_flags = 0;
} else {
reply_status = PROXY_STAT_OK;
/*
* This routine runs whenever a client connects to the socket dedicated
- * to the address verification service. All connection-management stuff
- * is handled by the common code in multi_server.c.
+ * to the proxymap service. All connection-management stuff is handled by
+ * the common code in multi_server.c.
*/
if (attr_scan(client_stream,
ATTR_FLAG_MORE | ATTR_FLAG_STRICT,
int status;
va_start(ap, format);
- status = vbounce_append(BOUNCE_FLAG_KEEP, message->queue_id,
+ status = vbounce_append(message->tflags, message->queue_id,
recipient->orig_rcpt, recipient->address, "none",
message->arrival_time, format, ap);
va_end(ap);
/*
* Update the message structure and log the message disposition.
*/
- message->flags |= defer_append(BOUNCE_FLAG_KEEP, message->queue_id,
+ message->flags |= defer_append(message->tflags, message->queue_id,
recipient->orig_rcpt, recipient->address,
"none", message->arrival_time, "%s", reason);
}
resolve_clnt_init(&reply);
for (recipient = list.info; recipient < list.info + list.len; recipient++) {
- /*
- * This may be a bit late in the game, but it is the most convenient
- * place to scrutinize the destination address syntax. We have a
- * complete queue file, so bouncing is easy. That luxury is not
- * available to the cleanup service. The main issue is that we want
- * to have this test in one place, instead of having to do this in
- * every front-ent program.
- */
- if ((at = strrchr(recipient->address, '@')) != 0
- && (at + 1)[strspn(at + 1, "[]0123456789.")] != 0
- && valid_hostname(at + 1, DONT_GRIPE) == 0) {
- qmgr_bounce_recipient(message, recipient,
- "bad host/domain syntax: \"%s\"", at + 1);
- continue;
- }
-
/*
* Resolve the destination to (transport, nexthop, address). The
* result address may differ from the one specified by the sender.
*/
smtpd_noop_cmds = string_list_init(MATCH_FLAG_NONE, var_smtpd_noop_cmds);
verp_clients = namadr_list_init(MATCH_FLAG_NONE, var_verp_clients);
- smtpd_check_init();
+ if (getuid() == 0 || getuid() == var_owner_uid)
+ smtpd_check_init();
debug_peer_init();
if (var_smtpd_sasl_enable)