Postfix3.3.1
bounce.c
[詳解]
1 /*++
2 /* NAME
3 /* bounce 8
4 /* SUMMARY
5 /* Postfix delivery status reports
6 /* SYNOPSIS
7 /* \fBbounce\fR [generic Postfix daemon options]
8 /* DESCRIPTION
9 /* The \fBbounce\fR(8) daemon maintains per-message log files with
10 /* delivery status information. Each log file is named after the
11 /* queue file that it corresponds to, and is kept in a queue subdirectory
12 /* named after the service name in the \fBmaster.cf\fR file (either
13 /* \fBbounce\fR, \fBdefer\fR or \fBtrace\fR).
14 /* This program expects to be run from the \fBmaster\fR(8) process
15 /* manager.
16 /*
17 /* The \fBbounce\fR(8) daemon processes two types of service requests:
18 /* .IP \(bu
19 /* Append a recipient (non-)delivery status record to a per-message
20 /* log file.
21 /* .IP \(bu
22 /* Enqueue a delivery status notification message, with a copy
23 /* of a per-message log file and of the corresponding message.
24 /* When the delivery status notification message is
25 /* enqueued successfully, the per-message log file is deleted.
26 /* .PP
27 /* The software does a best notification effort. A non-delivery
28 /* notification is sent even when the log file or the original
29 /* message cannot be read.
30 /*
31 /* Optionally, a bounce (defer, trace) client can request that the
32 /* per-message log file be deleted when the requested operation fails.
33 /* This is used by clients that cannot retry transactions by
34 /* themselves, and that depend on retry logic in their own client.
35 /* STANDARDS
36 /* RFC 822 (ARPA Internet Text Messages)
37 /* RFC 2045 (Format of Internet Message Bodies)
38 /* RFC 2822 (Internet Message Format)
39 /* RFC 3462 (Delivery Status Notifications)
40 /* RFC 3464 (Delivery Status Notifications)
41 /* RFC 3834 (Auto-Submitted: message header)
42 /* RFC 5322 (Internet Message Format)
43 /* RFC 6531 (Internationalized SMTP)
44 /* RFC 6532 (Internationalized Message Format)
45 /* RFC 6533 (Internationalized Delivery Status Notifications)
46 /* DIAGNOSTICS
47 /* Problems and transactions are logged to \fBsyslogd\fR(8).
48 /* CONFIGURATION PARAMETERS
49 /* .ad
50 /* .fi
51 /* Changes to \fBmain.cf\fR are picked up automatically, as \fBbounce\fR(8)
52 /* processes run for only a limited amount of time. Use the command
53 /* "\fBpostfix reload\fR" to speed up a change.
54 /*
55 /* The text below provides only a parameter summary. See
56 /* \fBpostconf\fR(5) for more details including examples.
57 /* .IP "\fB2bounce_notice_recipient (postmaster)\fR"
58 /* The recipient of undeliverable mail that cannot be returned to
59 /* the sender.
60 /* .IP "\fBbackwards_bounce_logfile_compatibility (yes)\fR"
61 /* Produce additional \fBbounce\fR(8) logfile records that can be read by
62 /* Postfix versions before 2.0.
63 /* .IP "\fBbounce_notice_recipient (postmaster)\fR"
64 /* The recipient of postmaster notifications with the message headers
65 /* of mail that Postfix did not deliver and of SMTP conversation
66 /* transcripts of mail that Postfix did not receive.
67 /* .IP "\fBbounce_size_limit (50000)\fR"
68 /* The maximal amount of original message text that is sent in a
69 /* non-delivery notification.
70 /* .IP "\fBbounce_template_file (empty)\fR"
71 /* Pathname of a configuration file with bounce message templates.
72 /* .IP "\fBconfig_directory (see 'postconf -d' output)\fR"
73 /* The default location of the Postfix main.cf and master.cf
74 /* configuration files.
75 /* .IP "\fBdaemon_timeout (18000s)\fR"
76 /* How much time a Postfix daemon process may take to handle a
77 /* request before it is terminated by a built-in watchdog timer.
78 /* .IP "\fBdelay_notice_recipient (postmaster)\fR"
79 /* The recipient of postmaster notifications with the message headers
80 /* of mail that cannot be delivered within $delay_warning_time time
81 /* units.
82 /* .IP "\fBdeliver_lock_attempts (20)\fR"
83 /* The maximal number of attempts to acquire an exclusive lock on a
84 /* mailbox file or \fBbounce\fR(8) logfile.
85 /* .IP "\fBdeliver_lock_delay (1s)\fR"
86 /* The time between attempts to acquire an exclusive lock on a mailbox
87 /* file or \fBbounce\fR(8) logfile.
88 /* .IP "\fBipc_timeout (3600s)\fR"
89 /* The time limit for sending or receiving information over an internal
90 /* communication channel.
91 /* .IP "\fBinternal_mail_filter_classes (empty)\fR"
92 /* What categories of Postfix-generated mail are subject to
93 /* before-queue content inspection by non_smtpd_milters, header_checks
94 /* and body_checks.
95 /* .IP "\fBmail_name (Postfix)\fR"
96 /* The mail system name that is displayed in Received: headers, in
97 /* the SMTP greeting banner, and in bounced mail.
98 /* .IP "\fBmax_idle (100s)\fR"
99 /* The maximum amount of time that an idle Postfix daemon process waits
100 /* for an incoming connection before terminating voluntarily.
101 /* .IP "\fBmax_use (100)\fR"
102 /* The maximal number of incoming connections that a Postfix daemon
103 /* process will service before terminating voluntarily.
104 /* .IP "\fBnotify_classes (resource, software)\fR"
105 /* The list of error classes that are reported to the postmaster.
106 /* .IP "\fBprocess_id (read-only)\fR"
107 /* The process ID of a Postfix command or daemon process.
108 /* .IP "\fBprocess_name (read-only)\fR"
109 /* The process name of a Postfix command or daemon process.
110 /* .IP "\fBqueue_directory (see 'postconf -d' output)\fR"
111 /* The location of the Postfix top-level queue directory.
112 /* .IP "\fBsyslog_facility (mail)\fR"
113 /* The syslog facility of Postfix logging.
114 /* .IP "\fBsyslog_name (see 'postconf -d' output)\fR"
115 /* A prefix that is prepended to the process name in syslog
116 /* records, so that, for example, "smtpd" becomes "prefix/smtpd".
117 /* .PP
118 /* Available in Postfix 3.0 and later:
119 /* .IP "\fBsmtputf8_autodetect_classes (sendmail, verify)\fR"
120 /* Detect that a message requires SMTPUTF8 support for the specified
121 /* mail origin classes.
122 /* .PP
123 /* Available in Postfix 3.3 and later:
124 /* .IP "\fBservice_name (read-only)\fR"
125 /* The master.cf service name of a Postfix daemon process.
126 /* FILES
127 /* /var/spool/postfix/bounce/* non-delivery records
128 /* /var/spool/postfix/defer/* non-delivery records
129 /* /var/spool/postfix/trace/* delivery status records
130 /* SEE ALSO
131 /* bounce(5), bounce message template format
132 /* qmgr(8), queue manager
133 /* postconf(5), configuration parameters
134 /* master(5), generic daemon options
135 /* master(8), process manager
136 /* syslogd(8), system logging
137 /* LICENSE
138 /* .ad
139 /* .fi
140 /* The Secure Mailer license must be distributed with this software.
141 /* AUTHOR(S)
142 /* Wietse Venema
143 /* IBM T.J. Watson Research
144 /* P.O. Box 704
145 /* Yorktown Heights, NY 10598, USA
146 /*
147 /* Wietse Venema
148 /* Google, Inc.
149 /* 111 8th Avenue
150 /* New York, NY 10011, USA
151 /*--*/
152 
153 /* System library. */
154 
155 #include <sys_defs.h>
156 #include <string.h>
157 #include <stdlib.h>
158 
159 /* Utility library. */
160 
161 #include <msg.h>
162 #include <vstring.h>
163 #include <vstream.h>
164 #include <stringops.h>
165 #include <load_file.h>
166 
167 /* Global library. */
168 
169 #include <mail_proto.h>
170 #include <mail_queue.h>
171 #include <mail_params.h>
172 #include <mail_version.h>
173 #include <mail_conf.h>
174 #include <bounce.h>
175 #include <mail_addr.h>
176 #include <rcpt_buf.h>
177 #include <dsb_scan.h>
178 
179 /* Single-threaded server skeleton. */
180 
181 #include <mail_server.h>
182 
183 /* Application-specific. */
184 
185 #include <bounce_service.h>
186 
187  /*
188  * Tunables.
189  */
198 
199  /*
200  * We're single threaded, so we can avoid some memory allocation overhead.
201  */
202 static VSTRING *queue_id;
203 static VSTRING *queue_name;
204 static RCPT_BUF *rcpt_buf;
205 static VSTRING *encoding;
206 static VSTRING *sender;
207 static VSTRING *dsn_envid;
208 static VSTRING *verp_delims;
209 static DSN_BUF *dsn_buf;
210 
211  /*
212  * Templates.
213  */
215 
216 #define STR vstring_str
217 
218 #define VS_NEUTER(s) printable(vstring_str(s), '?')
219 
220 /* bounce_append_proto - bounce_append server protocol */
221 
222 static int bounce_append_proto(char *service_name, VSTREAM *client)
223 {
224  const char *myname = "bounce_append_proto";
225  int flags;
226 
227  /*
228  * Read and validate the client request.
229  */
230  if (mail_command_server(client,
232  RECV_ATTR_STR(MAIL_ATTR_QUEUEID, queue_id),
233  RECV_ATTR_FUNC(rcpb_scan, (void *) rcpt_buf),
234  RECV_ATTR_FUNC(dsb_scan, (void *) dsn_buf),
235  ATTR_TYPE_END) != 4) {
236  msg_warn("malformed request");
237  return (-1);
238  }
239 
240  /*
241  * Sanitize input.
242  */
243  if (mail_queue_id_ok(STR(queue_id)) == 0) {
244  msg_warn("malformed queue id: %s", printable(STR(queue_id), '?'));
245  return (-1);
246  }
247  VS_NEUTER(rcpt_buf->address);
248  VS_NEUTER(rcpt_buf->orig_addr);
249  VS_NEUTER(rcpt_buf->dsn_orcpt);
250  VS_NEUTER(dsn_buf->status);
251  VS_NEUTER(dsn_buf->action);
252  VS_NEUTER(dsn_buf->reason);
253  VS_NEUTER(dsn_buf->dtype);
254  VS_NEUTER(dsn_buf->dtext);
255  VS_NEUTER(dsn_buf->mtype);
256  VS_NEUTER(dsn_buf->mname);
257  (void) RECIPIENT_FROM_RCPT_BUF(rcpt_buf);
258  (void) DSN_FROM_DSN_BUF(dsn_buf);
259 
260  /*
261  * Beware: some DSN or RECIPIENT fields may be null; access dsn_buf and
262  * rcpt_buf buffers instead. See DSN_FROM_DSN_BUF() and
263  * RECIPIENT_FROM_RCPT_BUF().
264  */
265  if (msg_verbose)
266  msg_info("%s: flags=0x%x service=%s id=%s org_to=%s to=%s off=%ld dsn_org=%s, notif=0x%x stat=%s act=%s why=%s",
267  myname, flags, service_name, STR(queue_id),
268  STR(rcpt_buf->orig_addr), STR(rcpt_buf->address),
269  rcpt_buf->offset, STR(rcpt_buf->dsn_orcpt),
270  rcpt_buf->dsn_notify, STR(dsn_buf->status),
271  STR(dsn_buf->action), STR(dsn_buf->reason));
272 
273  /*
274  * On request by the client, set up a trap to delete the log file in case
275  * of errors.
276  */
277  if (flags & BOUNCE_FLAG_CLEAN)
278  bounce_cleanup_register(service_name, STR(queue_id));
279 
280  /*
281  * Execute the request.
282  */
283  return (bounce_append_service(flags, service_name, STR(queue_id),
284  &rcpt_buf->rcpt, &dsn_buf->dsn));
285 }
286 
287 /* bounce_notify_proto - bounce_notify server protocol */
288 
289 static int bounce_notify_proto(char *service_name, VSTREAM *client,
290  int (*service) (int, char *, char *, char *,
291  char *, int, char *, char *, int,
292  BOUNCE_TEMPLATES *))
293 {
294  const char *myname = "bounce_notify_proto";
295  int flags;
296  int smtputf8;
297  int dsn_ret;
298 
299  /*
300  * Read and validate the client request.
301  */
302  if (mail_command_server(client,
304  RECV_ATTR_STR(MAIL_ATTR_QUEUE, queue_name),
305  RECV_ATTR_STR(MAIL_ATTR_QUEUEID, queue_id),
307  RECV_ATTR_INT(MAIL_ATTR_SMTPUTF8, &smtputf8),
310  RECV_ATTR_INT(MAIL_ATTR_DSN_RET, &dsn_ret),
311  ATTR_TYPE_END) != 8) {
312  msg_warn("malformed request");
313  return (-1);
314  }
315 
316  /*
317  * Sanitize input.
318  */
319  if (mail_queue_name_ok(STR(queue_name)) == 0) {
320  msg_warn("malformed queue name: %s", printable(STR(queue_name), '?'));
321  return (-1);
322  }
323  if (mail_queue_id_ok(STR(queue_id)) == 0) {
324  msg_warn("malformed queue id: %s", printable(STR(queue_id), '?'));
325  return (-1);
326  }
327  VS_NEUTER(encoding);
328  VS_NEUTER(sender);
329  VS_NEUTER(dsn_envid);
330  if (msg_verbose)
331  msg_info("%s: flags=0x%x service=%s queue=%s id=%s encoding=%s smtputf8=%d sender=%s envid=%s ret=0x%x",
332  myname, flags, service_name, STR(queue_name), STR(queue_id),
333  STR(encoding), smtputf8, STR(sender), STR(dsn_envid),
334  dsn_ret);
335 
336  /*
337  * On request by the client, set up a trap to delete the log file in case
338  * of errors.
339  */
340  if (flags & BOUNCE_FLAG_CLEAN)
341  bounce_cleanup_register(service_name, STR(queue_id));
342 
343  /*
344  * Execute the request.
345  */
346  return (service(flags, service_name, STR(queue_name),
347  STR(queue_id), STR(encoding), smtputf8,
348  STR(sender), STR(dsn_envid), dsn_ret,
349  bounce_templates));
350 }
351 
352 /* bounce_verp_proto - bounce_notify server protocol, VERP style */
353 
354 static int bounce_verp_proto(char *service_name, VSTREAM *client)
355 {
356  const char *myname = "bounce_verp_proto";
357  int flags;
358  int smtputf8;
359  int dsn_ret;
360 
361  /*
362  * Read and validate the client request.
363  */
364  if (mail_command_server(client,
366  RECV_ATTR_STR(MAIL_ATTR_QUEUE, queue_name),
367  RECV_ATTR_STR(MAIL_ATTR_QUEUEID, queue_id),
369  RECV_ATTR_INT(MAIL_ATTR_SMTPUTF8, &smtputf8),
372  RECV_ATTR_INT(MAIL_ATTR_DSN_RET, &dsn_ret),
373  RECV_ATTR_STR(MAIL_ATTR_VERPDL, verp_delims),
374  ATTR_TYPE_END) != 9) {
375  msg_warn("malformed request");
376  return (-1);
377  }
378 
379  /*
380  * Sanitize input.
381  */
382  if (mail_queue_name_ok(STR(queue_name)) == 0) {
383  msg_warn("malformed queue name: %s", printable(STR(queue_name), '?'));
384  return (-1);
385  }
386  if (mail_queue_id_ok(STR(queue_id)) == 0) {
387  msg_warn("malformed queue id: %s", printable(STR(queue_id), '?'));
388  return (-1);
389  }
390  VS_NEUTER(encoding);
391  VS_NEUTER(sender);
392  VS_NEUTER(dsn_envid);
393  VS_NEUTER(verp_delims);
394  if (strlen(STR(verp_delims)) != 2) {
395  msg_warn("malformed verp delimiter string: %s", STR(verp_delims));
396  return (-1);
397  }
398  if (msg_verbose)
399  msg_info("%s: flags=0x%x service=%s queue=%s id=%s encoding=%s smtputf8=%d sender=%s envid=%s ret=0x%x delim=%s",
400  myname, flags, service_name, STR(queue_name),
401  STR(queue_id), STR(encoding), smtputf8, STR(sender),
402  STR(dsn_envid), dsn_ret, STR(verp_delims));
403 
404  /*
405  * On request by the client, set up a trap to delete the log file in case
406  * of errors.
407  */
408  if (flags & BOUNCE_FLAG_CLEAN)
409  bounce_cleanup_register(service_name, STR(queue_id));
410 
411  /*
412  * Execute the request. Fall back to traditional notification if a bounce
413  * was returned as undeliverable, because we don't want to VERPify those.
414  */
415  if (!*STR(sender) || !strcasecmp_utf8(STR(sender),
417  msg_warn("request to send VERP-style notification of bounced mail");
418  return (bounce_notify_service(flags, service_name, STR(queue_name),
419  STR(queue_id), STR(encoding), smtputf8,
420  STR(sender), STR(dsn_envid), dsn_ret,
421  bounce_templates));
422  } else
423  return (bounce_notify_verp(flags, service_name, STR(queue_name),
424  STR(queue_id), STR(encoding), smtputf8,
425  STR(sender), STR(dsn_envid), dsn_ret,
426  STR(verp_delims), bounce_templates));
427 }
428 
429 /* bounce_one_proto - bounce_one server protocol */
430 
431 static int bounce_one_proto(char *service_name, VSTREAM *client)
432 {
433  const char *myname = "bounce_one_proto";
434  int flags;
435  int smtputf8;
436  int dsn_ret;
437 
438  /*
439  * Read and validate the client request.
440  */
441  if (mail_command_server(client,
443  RECV_ATTR_STR(MAIL_ATTR_QUEUE, queue_name),
444  RECV_ATTR_STR(MAIL_ATTR_QUEUEID, queue_id),
446  RECV_ATTR_INT(MAIL_ATTR_SMTPUTF8, &smtputf8),
449  RECV_ATTR_INT(MAIL_ATTR_DSN_RET, &dsn_ret),
450  RECV_ATTR_FUNC(rcpb_scan, (void *) rcpt_buf),
451  RECV_ATTR_FUNC(dsb_scan, (void *) dsn_buf),
452  ATTR_TYPE_END) != 10) {
453  msg_warn("malformed request");
454  return (-1);
455  }
456 
457  /*
458  * Sanitize input.
459  */
460  if (strcmp(service_name, MAIL_SERVICE_BOUNCE) != 0) {
461  msg_warn("wrong service name \"%s\" for one-recipient bouncing",
462  service_name);
463  return (-1);
464  }
465  if (mail_queue_name_ok(STR(queue_name)) == 0) {
466  msg_warn("malformed queue name: %s", printable(STR(queue_name), '?'));
467  return (-1);
468  }
469  if (mail_queue_id_ok(STR(queue_id)) == 0) {
470  msg_warn("malformed queue id: %s", printable(STR(queue_id), '?'));
471  return (-1);
472  }
473  VS_NEUTER(encoding);
474  VS_NEUTER(sender);
475  VS_NEUTER(dsn_envid);
476  VS_NEUTER(rcpt_buf->address);
477  VS_NEUTER(rcpt_buf->orig_addr);
478  VS_NEUTER(rcpt_buf->dsn_orcpt);
479  VS_NEUTER(dsn_buf->status);
480  VS_NEUTER(dsn_buf->action);
481  VS_NEUTER(dsn_buf->reason);
482  VS_NEUTER(dsn_buf->dtype);
483  VS_NEUTER(dsn_buf->dtext);
484  VS_NEUTER(dsn_buf->mtype);
485  VS_NEUTER(dsn_buf->mname);
486  (void) RECIPIENT_FROM_RCPT_BUF(rcpt_buf);
487  (void) DSN_FROM_DSN_BUF(dsn_buf);
488 
489  /*
490  * Beware: some DSN or RECIPIENT fields may be null; access dsn_buf and
491  * rcpt_buf buffers instead. See DSN_FROM_DSN_BUF() and
492  * RECIPIENT_FROM_RCPT_BUF().
493  */
494  if (msg_verbose)
495  msg_info("%s: flags=0x%x queue=%s id=%s encoding=%s smtputf8=%d sender=%s envid=%s dsn_ret=0x%x orig_to=%s to=%s off=%ld dsn_orig=%s notif=0x%x stat=%s act=%s why=%s",
496  myname, flags, STR(queue_name), STR(queue_id),
497  STR(encoding), smtputf8, STR(sender), STR(dsn_envid),
498  dsn_ret, STR(rcpt_buf->orig_addr), STR(rcpt_buf->address),
499  rcpt_buf->offset, STR(rcpt_buf->dsn_orcpt),
500  rcpt_buf->dsn_notify, STR(dsn_buf->status),
501  STR(dsn_buf->action), STR(dsn_buf->reason));
502 
503  /*
504  * Execute the request.
505  */
506  return (bounce_one_service(flags, STR(queue_name), STR(queue_id),
507  STR(encoding), smtputf8, STR(sender),
508  STR(dsn_envid), dsn_ret, rcpt_buf,
509  dsn_buf, bounce_templates));
510 }
511 
512 /* bounce_service - parse bounce command type and delegate */
513 
514 static void bounce_service(VSTREAM *client, char *service_name, char **argv)
515 {
516  int command;
517  int status;
518 
519  /*
520  * Sanity check. This service takes no command-line arguments. The
521  * service name should be usable as a subdirectory name.
522  */
523  if (argv[0])
524  msg_fatal("unexpected command-line argument: %s", argv[0]);
525  if (mail_queue_name_ok(service_name) == 0)
526  msg_fatal("malformed service name: %s", service_name);
527 
528  /*
529  * Read and validate the first parameter of the client request. Let the
530  * request-specific protocol routines take care of the remainder.
531  */
533  RECV_ATTR_INT(MAIL_ATTR_NREQ, &command), 0) != 1) {
534  msg_warn("malformed request");
535  status = -1;
536  } else if (command == BOUNCE_CMD_VERP) {
537  status = bounce_verp_proto(service_name, client);
538  } else if (command == BOUNCE_CMD_FLUSH) {
539  status = bounce_notify_proto(service_name, client,
541  } else if (command == BOUNCE_CMD_WARN) {
542  status = bounce_notify_proto(service_name, client,
544  } else if (command == BOUNCE_CMD_TRACE) {
545  status = bounce_notify_proto(service_name, client,
547  } else if (command == BOUNCE_CMD_APPEND) {
548  status = bounce_append_proto(service_name, client);
549  } else if (command == BOUNCE_CMD_ONE) {
550  status = bounce_one_proto(service_name, client);
551  } else {
552  msg_warn("unknown command: %d", command);
553  status = -1;
554  }
555 
556  /*
557  * When the request has completed, send the completion status to the
558  * client.
559  */
560  attr_print(client, ATTR_FLAG_NONE,
562  ATTR_TYPE_END);
563  vstream_fflush(client);
564 
565  /*
566  * When a cleanup trap was set, delete the log file in case of error.
567  * This includes errors while sending the completion status to the
568  * client.
569  */
570  if (bounce_cleanup_path) {
571  if (status || vstream_ferror(client))
574  }
575 }
576 
577 static void load_helper(VSTREAM *stream, void *context)
578 {
579  BOUNCE_TEMPLATES *templates = (BOUNCE_TEMPLATES *) context;
580 
581  bounce_templates_load(stream, templates);
582 }
583 
584 /* pre_jail_init - pre-jail initialization */
585 
586 static void pre_jail_init(char *unused_name, char **unused_argv)
587 {
588 
589  /*
590  * Bundle up a bunch of bounce template information.
591  */
592  bounce_templates = bounce_templates_create();
593 
594  /*
595  * Load the alternate message files (if specified) before entering the
596  * chroot jail.
597  */
598  if (*var_bounce_tmpl)
599  load_file(var_bounce_tmpl, load_helper, (void *) bounce_templates);
600 }
601 
602 /* post_jail_init - initialize after entering chroot jail */
603 
604 static void post_jail_init(char *service_name, char **unused_argv)
605 {
606 
607  /*
608  * Special case: dump bounce templates. This is not part of the master(5)
609  * public interface. This internal interface is used by the postconf
610  * command. It was implemented before bounce templates were isolated into
611  * modules that could have been called directly.
612  */
613  if (strcmp(service_name, "dump_templates") == 0) {
614  bounce_templates_dump(VSTREAM_OUT, bounce_templates);
616  exit(0);
617  }
618  if (strcmp(service_name, "expand_templates") == 0) {
619  bounce_templates_expand(VSTREAM_OUT, bounce_templates);
621  exit(0);
622  }
623 
624  /*
625  * Initialize. We're single threaded so we can reuse some memory upon
626  * successive requests.
627  */
628  queue_id = vstring_alloc(10);
629  queue_name = vstring_alloc(10);
630  rcpt_buf = rcpb_create();
631  encoding = vstring_alloc(10);
632  sender = vstring_alloc(10);
633  dsn_envid = vstring_alloc(10);
634  verp_delims = vstring_alloc(10);
635  dsn_buf = dsb_create();
636 }
637 
639 
640 /* main - the main program */
641 
642 int main(int argc, char **argv)
643 {
644  static const CONFIG_INT_TABLE int_table[] = {
646  0,
647  };
648  static const CONFIG_TIME_TABLE time_table[] = {
651  0,
652  };
653  static const CONFIG_STR_TABLE str_table[] = {
659  0,
660  };
661 
662  /*
663  * Fingerprint executables and core dumps.
664  */
666 
667  /*
668  * Pass control to the single-threaded service skeleton.
669  */
670  single_server_main(argc, argv, bounce_service,
671  CA_MAIL_SERVER_INT_TABLE(int_table),
672  CA_MAIL_SERVER_STR_TABLE(str_table),
673  CA_MAIL_SERVER_TIME_TABLE(time_table),
674  CA_MAIL_SERVER_PRE_INIT(pre_jail_init),
675  CA_MAIL_SERVER_POST_INIT(post_jail_init),
677  0);
678 }
int msg_verbose
Definition: msg.c:177
int bounce_one_service(int flags, char *queue_name, char *queue_id, char *encoding, int smtputf8, char *orig_sender, char *dsn_envid, int dsn_ret, RCPT_BUF *rcpt_buf, DSN_BUF *dsn_buf, BOUNCE_TEMPLATES *ts)
#define DEF_BOUNCE_LIMIT
Definition: mail_params.h:1958
#define ATTR_FLAG_NONE
Definition: attr.h:98
#define CA_MAIL_SERVER_UNLIMITED
Definition: mail_server.h:70
DSN_BUF * dsb_create(void)
Definition: dsn_buf.c:169
char * var_bounce_tmpl
Definition: bounce.c:197
#define STR
Definition: bounce.c:216
int bounce_notify_service(int flags, char *service, char *queue_name, char *queue_id, char *encoding, int smtputf8, char *recipient, char *dsn_envid, int dsn_ret, BOUNCE_TEMPLATES *ts)
#define MAIL_ATTR_ENCODING
Definition: mail_proto.h:202
#define VAR_BOUNCE_RCPT
Definition: mail_params.h:157
int mail_queue_id_ok(const char *queue_id)
Definition: mail_queue.c:296
#define CA_MAIL_SERVER_STR_TABLE(v)
Definition: mail_server.h:57
#define VSTREAM_OUT
Definition: vstream.h:67
char * var_delay_rcpt
Definition: bounce.c:196
int bounce_warn_service(int, char *, char *, char *, char *, int, char *, char *, int, BOUNCE_TEMPLATES *)
#define DEF_DELAY_RCPT
Definition: mail_params.h:166
#define BOUNCE_CMD_TRACE
Definition: bounce.h:48
#define BOUNCE_CMD_ONE
Definition: bounce.h:47
int rcpb_scan(ATTR_SCAN_MASTER_FN scan_fn, VSTREAM *fp, int flags, void *ptr)
Definition: rcpt_buf.c:118
DSN dsn
Definition: dsn_buf.h:28
VSTRING * mname
Definition: dsn_buf.h:33
#define DEF_BOUNCE_RCPT
Definition: mail_params.h:158
#define RECV_ATTR_INT(name, val)
Definition: attr.h:71
#define ATTR_TYPE_END
Definition: attr.h:39
VSTRING * dsn_orcpt
Definition: rcpt_buf.h:33
#define strcasecmp_utf8(s1, s2)
Definition: stringops.h:75
char * var_bounce_rcpt
Definition: bounce.c:194
int dsb_scan(ATTR_SCAN_MASTER_FN scan_fn, VSTREAM *fp, int flags, void *ptr)
Definition: dsb_scan.c:48
int mail_queue_name_ok(const char *queue_name)
Definition: mail_queue.c:281
#define BOUNCE_FLAG_CLEAN
Definition: bounce.h:61
void bounce_cleanup_register(char *service, char *queue_id)
void bounce_templates_expand(VSTREAM *, BOUNCE_TEMPLATES *)
RECIPIENT rcpt
Definition: rcpt_buf.h:30
#define DEF_NOTIFY_CLASSES
Definition: mail_params.h:73
#define BOUNCE_CMD_APPEND
Definition: bounce.h:43
#define MAIL_ATTR_QUEUE
Definition: mail_proto.h:129
#define CA_MAIL_SERVER_POST_INIT(v)
Definition: mail_server.h:65
#define CA_MAIL_SERVER_INT_TABLE(v)
Definition: mail_server.h:56
int main(int argc, char **argv)
Definition: bounce.c:642
RCPT_BUF * rcpb_create(void)
Definition: rcpt_buf.c:80
#define attr_print
Definition: attr.h:109
int bounce_notify_verp(int flags, char *service, char *queue_name, char *queue_id, char *encoding, int smtputf8, char *recipient, char *dsn_envid, int dsn_ret, char *verp_delims, BOUNCE_TEMPLATES *ts)
#define DSN_FROM_DSN_BUF(dsb)
Definition: dsn_buf.h:68
char * var_notify_classes
Definition: bounce.c:193
int dsn_notify
Definition: rcpt_buf.h:34
int var_bounce_limit
Definition: bounce.c:190
#define MAIL_ATTR_NREQ
Definition: mail_proto.h:125
VSTRING * address
Definition: rcpt_buf.h:31
VSTRING * dtype
Definition: dsn_buf.h:34
#define MAIL_ATTR_SMTPUTF8
Definition: mail_proto.h:277
VSTRING * action
Definition: dsn_buf.h:31
#define VAR_BOUNCE_TMPL
Definition: mail_params.h:3180
#define BOUNCE_CMD_VERP
Definition: bounce.h:46
void msg_warn(const char *fmt,...)
Definition: msg.c:215
#define DEF_2BOUNCE_RCPT
Definition: mail_params.h:162
VSTRING * vstring_alloc(ssize_t len)
Definition: vstring.c:353
#define MAIL_ATTR_DSN_RET
Definition: mail_proto.h:274
#define DEF_BOUNCE_TMPL
Definition: mail_params.h:3181
#define BOUNCE_CMD_WARN
Definition: bounce.h:45
#define MAIL_VERSION_STAMP_ALLOCATE
Definition: mail_version.h:67
#define VAR_DELAY_WARN_TIME
Definition: mail_params.h:765
#define MAIL_ATTR_DSN_ENVID
Definition: mail_proto.h:273
BOUNCE_TEMPLATES * bounce_templates
Definition: bounce.c:214
#define CA_MAIL_SERVER_TIME_TABLE(v)
Definition: mail_server.h:59
#define MAIL_ATTR_STATUS
Definition: mail_proto.h:126
#define SEND_ATTR_INT(name, val)
Definition: attr.h:63
BOUNCE_TEMPLATES * bounce_templates_create(void)
int var_delay_warn_time
Definition: bounce.c:192
#define MAIL_SERVICE_BOUNCE
Definition: mail_proto.h:38
NORETURN msg_fatal(const char *fmt,...)
Definition: msg.c:249
void bounce_cleanup_log(void)
#define VAR_NOTIFY_CLASSES
Definition: mail_params.h:72
int vstream_fflush(VSTREAM *stream)
Definition: vstream.c:1257
const char * mail_addr_double_bounce(void)
Definition: mail_addr.c:64
VSTRING * orig_addr
Definition: rcpt_buf.h:32
int bounce_append_service(int unused_flags, char *service, char *queue_id, RECIPIENT *rcpt, DSN *dsn)
#define VAR_BOUNCE_LIMIT
Definition: mail_params.h:1957
#define RECIPIENT_FROM_RCPT_BUF(buf)
Definition: rcpt_buf.h:43
VSTRING * mtype
Definition: dsn_buf.h:32
VSTRING * reason
Definition: dsn_buf.h:37
void bounce_cleanup_unregister(void)
int bounce_trace_service(int, char *, char *, char *, char *, int, char *, char *, int, BOUNCE_TEMPLATES *)
#define VS_NEUTER(s)
Definition: bounce.c:218
#define BOUNCE_CMD_FLUSH
Definition: bounce.h:44
MAIL_VERSION_STAMP_DECLARE
Definition: bounce.c:638
#define VAR_DELAY_RCPT
Definition: mail_params.h:165
#define MAIL_ATTR_SENDER
Definition: mail_proto.h:131
NORETURN single_server_main(int, char **, SINGLE_SERVER_FN,...)
#define RECV_ATTR_FUNC(func, val)
Definition: attr.h:77
VSTRING * bounce_cleanup_path
VSTRING * dtext
Definition: dsn_buf.h:35
long offset
Definition: rcpt_buf.h:35
void bounce_templates_dump(VSTREAM *, BOUNCE_TEMPLATES *)
#define MAIL_ATTR_QUEUEID
Definition: mail_proto.h:130
void bounce_templates_load(VSTREAM *, BOUNCE_TEMPLATES *)
void load_file(const char *path, LOAD_FILE_FN action, void *context)
Definition: load_file.c:53
char * printable(char *string, int replacement)
Definition: printable.c:49
#define attr_scan
Definition: attr.h:111
#define vstream_ferror(vp)
Definition: vstream.h:120
#define MAIL_ATTR_VERPDL
Definition: mail_proto.h:136
char * var_2bounce_rcpt
Definition: bounce.c:195
#define ATTR_FLAG_MORE
Definition: attr.h:101
VSTRING * status
Definition: dsn_buf.h:30
#define MAIL_ATTR_FLAGS
Definition: mail_proto.h:128
#define DEF_MAX_QUEUE_TIME
Definition: mail_params.h:754
#define VAR_MAX_QUEUE_TIME
Definition: mail_params.h:753
int var_max_queue_time
Definition: bounce.c:191
#define VAR_2BOUNCE_RCPT
Definition: mail_params.h:161
#define CA_MAIL_SERVER_PRE_INIT(v)
Definition: mail_server.h:64
#define RECV_ATTR_STR(name, val)
Definition: attr.h:72
int mail_command_server(VSTREAM *stream,...)
#define ATTR_FLAG_STRICT
Definition: attr.h:103
void msg_info(const char *fmt,...)
Definition: msg.c:199
#define DEF_DELAY_WARN_TIME
Definition: mail_params.h:766