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,

Reply via email to