Postfix3.3.1
unknown.c
[詳解]
1 /*++
2 /* NAME
3 /* unknown 3
4 /* SUMMARY
5 /* delivery of unknown recipients
6 /* SYNOPSIS
7 /* #include "local.h"
8 /*
9 /* int deliver_unknown(state, usr_attr)
10 /* LOCAL_STATE state;
11 /* USER_ATTR usr_attr;
12 /* DESCRIPTION
13 /* deliver_unknown() delivers a message for unknown recipients.
14 /* .IP \(bu
15 /* If an alternative message transport is specified via the
16 /* fallback_transport parameter, delivery is delegated to the
17 /* named transport.
18 /* .IP \(bu
19 /* If an alternative address is specified via the luser_relay
20 /* configuration parameter, mail is forwarded to that address.
21 /* .IP \(bu
22 /* Otherwise the recipient is bounced.
23 /* .PP
24 /* The luser_relay parameter is subjected to $name expansion of
25 /* the standard message attributes: $user, $home, $shell, $domain,
26 /* $recipient, $mailbox, $extension, $recipient_delimiter, not
27 /* all of which actually make sense.
28 /*
29 /* Arguments:
30 /* .IP state
31 /* Message delivery attributes (sender, recipient etc.).
32 /* Attributes describing alias, include or forward expansion.
33 /* A table with the results from expanding aliases or lists.
34 /* A table with delivered-to: addresses taken from the message.
35 /* .IP usr_attr
36 /* Attributes describing user rights and environment.
37 /* DIAGNOSTICS
38 /* The result status is non-zero when delivery should be tried again.
39 /* LICENSE
40 /* .ad
41 /* .fi
42 /* The Secure Mailer license must be distributed with this software.
43 /* AUTHOR(S)
44 /* Wietse Venema
45 /* IBM T.J. Watson Research
46 /* P.O. Box 704
47 /* Yorktown Heights, NY 10598, USA
48 /*--*/
49 
50 /* System library. */
51 
52 #include <sys_defs.h>
53 #include <string.h>
54 
55 #ifdef STRCASECMP_IN_STRINGS_H
56 #include <strings.h>
57 #endif
58 
59 /* Utility library. */
60 
61 #include <msg.h>
62 #include <stringops.h>
63 #include <mymalloc.h>
64 #include <vstring.h>
65 
66 /* Global library. */
67 
68 #include <been_here.h>
69 #include <mail_params.h>
70 #include <mail_proto.h>
71 #include <bounce.h>
72 #include <mail_addr.h>
73 #include <sent.h>
74 #include <deliver_pass.h>
75 #include <defer.h>
76 #include <canon_addr.h>
77 
78 /* Application-specific. */
79 
80 #include "local.h"
81 
82 #define STREQ(x,y) (strcasecmp((x),(y)) == 0)
83 
84 /* deliver_unknown - delivery for unknown recipients */
85 
87 {
88  const char *myname = "deliver_unknown";
89  int status;
90  VSTRING *expand_luser;
91  VSTRING *canon_luser;
92  static MAPS *transp_maps;
93  const char *map_transport;
94 
95  /*
96  * Make verbose logging easier to understand.
97  */
98  state.level++;
99  if (msg_verbose)
100  MSG_LOG_STATE(myname, state);
101 
102  /*
103  * DUPLICATE/LOOP ELIMINATION
104  *
105  * Don't deliver the same user twice.
106  */
107  if (been_here(state.dup_filter, "%s %s", myname, state.msg_attr.local))
108  return (0);
109 
110  /*
111  * The fall-back transport specifies a delivery machanism that handles
112  * users not found in the aliases or UNIX passwd databases.
113  */
114  if (*var_fbck_transp_maps && transp_maps == 0)
118  /* The -1 is a hint for the down-stream deliver_completed() function. */
119  if (transp_maps
120  && (map_transport = maps_find(transp_maps, state.msg_attr.user,
121  DICT_FLAG_NONE)) != 0) {
122  state.msg_attr.rcpt.offset = -1L;
123  return (deliver_pass(MAIL_CLASS_PRIVATE, map_transport,
124  state.request, &state.msg_attr.rcpt));
125  } else if (transp_maps && transp_maps->error != 0) {
126  /* Details in the logfile. */
127  dsb_simple(state.msg_attr.why, "4.3.0", "table lookup failure");
128  return (defer_append(BOUNCE_FLAGS(state.request),
129  BOUNCE_ATTR(state.msg_attr)));
130  }
131  if (*var_fallback_transport) {
132  state.msg_attr.rcpt.offset = -1L;
134  state.request, &state.msg_attr.rcpt));
135  }
136 
137  /*
138  * Subject the luser_relay address to $name expansion, disable
139  * propagation of unmatched address extension, and re-inject the address
140  * into the delivery machinery. Do not give special treatment to "|stuff"
141  * or /stuff.
142  */
143  if (*var_luser_relay) {
144  state.msg_attr.unmatched = 0;
145  expand_luser = vstring_alloc(100);
146  canon_luser = vstring_alloc(100);
147  local_expand(expand_luser, var_luser_relay, &state, &usr_attr, (void *) 0);
148  /* In case luser_relay specifies a domain-less address. */
149  canon_addr_external(canon_luser, vstring_str(expand_luser));
150  /* Assumes that the address resolver won't change the address. */
151  if (STREQ(vstring_str(canon_luser), state.msg_attr.rcpt.address)) {
152  dsb_simple(state.msg_attr.why, "5.1.1",
153  "unknown user: \"%s\"", state.msg_attr.user);
154  status = bounce_append(BOUNCE_FLAGS(state.request),
155  BOUNCE_ATTR(state.msg_attr));
156  } else {
157  status = deliver_resolve_addr(state, usr_attr, STR(expand_luser));
158  }
159  vstring_free(canon_luser);
160  vstring_free(expand_luser);
161  return (status);
162  }
163 
164  /*
165  * If no alias was found for a required reserved name, toss the message
166  * into the bit bucket, and issue a warning instead.
167  */
170  msg_warn("required alias not found: %s", state.msg_attr.user);
171  dsb_simple(state.msg_attr.why, "2.0.0", "discarded");
172  return (sent(BOUNCE_FLAGS(state.request), SENT_ATTR(state.msg_attr)));
173  }
174 
175  /*
176  * Bounce the message when no luser relay is specified.
177  */
178  dsb_simple(state.msg_attr.why, "5.1.1",
179  "unknown user: \"%s\"", state.msg_attr.user);
180  return (bounce_append(BOUNCE_FLAGS(state.request),
181  BOUNCE_ATTR(state.msg_attr)));
182 }
int msg_verbose
Definition: msg.c:177
#define SENT_ATTR(attr)
Definition: local.h:142
#define BOUNCE_ATTR(attr)
Definition: local.h:134
int deliver_resolve_addr(LOCAL_STATE, USER_ATTR, char *)
Definition: resolve.c:73
#define MAIL_ADDR_POSTMASTER
Definition: mail_addr.h:17
const char * address
#define vstring_str(vp)
Definition: vstring.h:71
char * local
Definition: local.h:81
Definition: maps.h:22
#define DICT_FLAG_UTF8_REQUEST
Definition: dict.h:130
char * var_fbck_transp_maps
Definition: local.c:665
#define STREQ(x, y)
Definition: unknown.c:82
DELIVER_REQUEST * request
Definition: local.h:113
#define BOUNCE_FLAGS(request)
int bounce_append(int flags, const char *id, MSG_STATS *stats, RECIPIENT *rcpt, const char *relay, DSN *dsn)
Definition: bounce.c:222
BH_TABLE * dup_filter
Definition: local.h:111
char * unmatched
Definition: local.h:84
int been_here(BH_TABLE *dup_filter, const char *fmt,...)
Definition: been_here.c:124
MAPS * maps_create(const char *title, const char *map_names, int dict_flags)
Definition: maps.c:112
char * user
Definition: local.h:82
VSTRING * canon_addr_external(VSTRING *result, const char *addr)
Definition: canon_addr.c:57
#define DICT_FLAG_LOCK
Definition: dict.h:116
DELIVER_ATTR msg_attr
Definition: local.h:110
#define STR(x)
Definition: anvil.c:518
#define MAIL_ADDR_MAIL_DAEMON
Definition: mail_addr.h:18
void msg_warn(const char *fmt,...)
Definition: msg.c:215
VSTRING * vstring_alloc(ssize_t len)
Definition: vstring.c:353
int deliver_pass(const char *class, const char *service, DELIVER_REQUEST *request, RECIPIENT *rcpt)
Definition: deliver_pass.c:160
DSN_BUF * dsb_simple(DSN_BUF *dsb, const char *status, const char *format,...)
Definition: dsn_buf.c:275
char * var_luser_relay
Definition: local.c:659
int error
Definition: maps.h:25
DSN_BUF * why
Definition: local.h:92
int level
Definition: local.h:109
int deliver_unknown(LOCAL_STATE state, USER_ATTR usr_attr)
Definition: unknown.c:86
#define VAR_FBCK_TRANSP_MAPS
Definition: mail_params.h:599
int local_expand(VSTRING *, const char *, LOCAL_STATE *, USER_ATTR *, const char *)
Definition: local_expand.c:166
VSTRING * vstring_free(VSTRING *vp)
Definition: vstring.c:380
char * var_fallback_transport
Definition: local.c:664
#define DICT_FLAG_NO_REGSUB
Definition: dict.h:121
int defer_append(int flags, const char *id, MSG_STATS *stats, RECIPIENT *rcpt, const char *relay, DSN *dsn)
Definition: defer.c:187
RECIPIENT rcpt
Definition: local.h:79
int sent(int flags, const char *id, MSG_STATS *stats, RECIPIENT *recipient, const char *relay, DSN *dsn)
Definition: sent.c:95
#define MSG_LOG_STATE(m, p)
Definition: local.h:150
#define DICT_FLAG_NONE
Definition: dict.h:109
const char * maps_find(MAPS *maps, const char *name, int flags)
Definition: maps.c:162
#define MAIL_CLASS_PRIVATE
Definition: mail_proto.h:96