William Ono: > I was hoping that setting mailbox_transport_maps to the same LDAP map as > local_recipient_maps would cause local to tempfail rather than bounce in > this case. It turns out that it does not.
The same error happens in mailbox_command_maps, mailbox_transport_maps, and fallback_transport_maps. That's three for the price of one. A variant of this occurs in the code that expands the owner-alias, while returning non-deliverable mail to a local alias. With the attached fix, Postfix should tempfail the delivery instead of pretending that the lookup produced a "not found" result. See attached file: 20110426-local-maps-find-patch. Wietse
20110426 Bugfix: the local(8) delivery agent ignored table lookup errors in mailbox_command_maps, mailbox_transport_maps, fallback_transport_maps and (while bouncing mail to alias) alias owner lookup. Problem reported by William Ono. Files: local/command.c, local/mailbox.c, local/unknown.c, local/bounce_workaround.c. diff -cr -C4 /var/tmp/postfix-2.9-20110323/src/local/Makefile.in src/local/Makefile.in *** /var/tmp/postfix-2.9-20110323/src/local/Makefile.in Sun Jan 9 17:12:05 2011 --- src/local/Makefile.in Tue Apr 26 16:28:59 2011 *************** *** 105,112 **** --- 105,113 ---- bounce_workaround.o: ../../include/attr.h bounce_workaround.o: ../../include/been_here.h bounce_workaround.o: ../../include/bounce.h bounce_workaround.o: ../../include/canon_addr.h + bounce_workaround.o: ../../include/defer.h bounce_workaround.o: ../../include/deliver_request.h bounce_workaround.o: ../../include/delivered_hdr.h bounce_workaround.o: ../../include/dict.h bounce_workaround.o: ../../include/dsn.h diff -cr -C4 /var/tmp/postfix-2.9-20110323/src/local/bounce_workaround.c src/local/bounce_workaround.c *** /var/tmp/postfix-2.9-20110323/src/local/bounce_workaround.c Sat Feb 13 21:00:24 2010 --- src/local/bounce_workaround.c Tue Apr 26 16:44:22 2011 *************** *** 76,83 **** --- 76,84 ---- #include <mail_params.h> #include <strip_addr.h> #include <stringops.h> #include <bounce.h> + #include <defer.h> #include <split_addr.h> #include <canon_addr.h> /* Application-specific. */ *************** *** 96,126 **** if (var_ownreq_special) { char *stripped_recipient; char *owner_alias; const char *owner_expansion; #define FIND_OWNER(lhs, rhs, addr) { \ lhs = concatenate("owner-", addr, (char *) 0); \ (void) split_at_right(lhs, '@'); \ rhs = maps_find(alias_maps, lhs, DICT_FLAG_NONE); \ } FIND_OWNER(owner_alias, owner_expansion, state.msg_attr.rcpt.address); ! if (owner_expansion == 0 && (stripped_recipient = strip_addr(state.msg_attr.rcpt.address, (char **) 0, *var_rcpt_delim)) != 0) { myfree(owner_alias); FIND_OWNER(owner_alias, owner_expansion, stripped_recipient); myfree(stripped_recipient); } ! if (owner_expansion != 0) { canon_owner = canon_addr_internal(vstring_alloc(10), var_exp_own_alias ? owner_expansion : owner_alias); SET_OWNER_ATTR(state.msg_attr, STR(canon_owner), state.level); } myfree(owner_alias); } /* * Send a delivery status notification with a single recipient to the --- 97,133 ---- if (var_ownreq_special) { char *stripped_recipient; char *owner_alias; const char *owner_expansion; + int saved_dict_errno; #define FIND_OWNER(lhs, rhs, addr) { \ lhs = concatenate("owner-", addr, (char *) 0); \ (void) split_at_right(lhs, '@'); \ rhs = maps_find(alias_maps, lhs, DICT_FLAG_NONE); \ } + dict_errno = 0; FIND_OWNER(owner_alias, owner_expansion, state.msg_attr.rcpt.address); ! if ((saved_dict_errno = dict_errno) == 0 && owner_expansion == 0 && (stripped_recipient = strip_addr(state.msg_attr.rcpt.address, (char **) 0, *var_rcpt_delim)) != 0) { myfree(owner_alias); FIND_OWNER(owner_alias, owner_expansion, stripped_recipient); myfree(stripped_recipient); } ! if ((saved_dict_errno = dict_errno) == 0 && owner_expansion != 0) { canon_owner = canon_addr_internal(vstring_alloc(10), var_exp_own_alias ? owner_expansion : owner_alias); SET_OWNER_ATTR(state.msg_attr, STR(canon_owner), state.level); } myfree(owner_alias); + if (saved_dict_errno != 0) + /* At this point, canon_owner == 0. */ + return (defer_append(BOUNCE_FLAGS(state.request), + BOUNCE_ATTR(state.msg_attr))); } /* * Send a delivery status notification with a single recipient to the diff -cr -C4 /var/tmp/postfix-2.9-20110323/src/local/mailbox.c src/local/mailbox.c *** /var/tmp/postfix-2.9-20110323/src/local/mailbox.c Fri Jul 25 21:21:22 2008 --- src/local/mailbox.c Tue Apr 26 15:12:46 2011 *************** *** 277,291 **** --- 277,297 ---- if (*var_mbox_transp_maps && transp_maps == 0) transp_maps = maps_create(VAR_MBOX_TRANSP_MAPS, var_mbox_transp_maps, DICT_FLAG_LOCK | DICT_FLAG_NO_REGSUB); /* The -1 is a hint for the down-stream deliver_completed() function. */ + dict_errno = 0; if (*var_mbox_transp_maps && (map_transport = maps_find(transp_maps, state.msg_attr.user, DICT_FLAG_NONE)) != 0) { state.msg_attr.rcpt.offset = -1L; *statusp = deliver_pass(MAIL_CLASS_PRIVATE, map_transport, state.request, &state.msg_attr.rcpt); return (YES); + } else if (dict_errno != 0) { + /* Details in the logfile. */ + dsb_simple(state.msg_attr.why, "4.3.0", "table lookup failure"); + *statusp = DEL_STAT_DEFER; + return (YES); } if (*var_mailbox_transport) { state.msg_attr.rcpt.offset = -1L; *statusp = deliver_pass(MAIL_CLASS_PRIVATE, var_mailbox_transport, *************** *** 318,329 **** --- 324,340 ---- if (*var_mailbox_cmd_maps && cmd_maps == 0) cmd_maps = maps_create(VAR_MAILBOX_CMD_MAPS, var_mailbox_cmd_maps, DICT_FLAG_LOCK | DICT_FLAG_PARANOID); + dict_errno = 0; if (*var_mailbox_cmd_maps && (map_command = maps_find(cmd_maps, state.msg_attr.user, DICT_FLAG_NONE)) != 0) { status = deliver_command(state, usr_attr, map_command); + } else if (dict_errno != 0) { + /* Details in the logfile. */ + dsb_simple(state.msg_attr.why, "4.3.0", "table lookup failure"); + status = DEL_STAT_DEFER; } else if (*var_mailbox_command) { status = deliver_command(state, usr_attr, var_mailbox_command); } else if (*var_home_mailbox && LAST_CHAR(var_home_mailbox) == '/') { path = concatenate(usr_attr.home, "/", var_home_mailbox, (char *) 0); diff -cr -C4 /var/tmp/postfix-2.9-20110323/src/local/unknown.c src/local/unknown.c *** /var/tmp/postfix-2.9-20110323/src/local/unknown.c Tue May 15 16:14:28 2007 --- src/local/unknown.c Tue Apr 26 15:11:43 2011 *************** *** 109,122 **** --- 109,127 ---- if (*var_fbck_transp_maps && transp_maps == 0) transp_maps = maps_create(VAR_FBCK_TRANSP_MAPS, var_fbck_transp_maps, DICT_FLAG_LOCK | DICT_FLAG_NO_REGSUB); /* The -1 is a hint for the down-stream deliver_completed() function. */ + dict_errno = 0; if (*var_fbck_transp_maps && (map_transport = maps_find(transp_maps, state.msg_attr.user, DICT_FLAG_NONE)) != 0) { state.msg_attr.rcpt.offset = -1L; return (deliver_pass(MAIL_CLASS_PRIVATE, map_transport, state.request, &state.msg_attr.rcpt)); + } else if (dict_errno != 0) { + /* Details in the logfile. */ + dsb_simple(state.msg_attr.why, "4.3.0", "table lookup failure"); + return (DEL_STAT_DEFER); } if (*var_fallback_transport) { state.msg_attr.rcpt.offset = -1L; return (deliver_pass(MAIL_CLASS_PRIVATE, var_fallback_transport,