7 /* Postfix local mail pickup
9 /* \fBpickup\fR [generic Postfix daemon options]
11 /* The \fBpickup\fR(8) daemon waits for hints that new mail has been
12 /* dropped into the \fBmaildrop\fR directory, and feeds it into the
13 /* \fBcleanup\fR(8) daemon.
14 /* Ill-formatted files are deleted without notifying the originator.
15 /* This program expects to be run from the \fBmaster\fR(8) process
20 /* None. The \fBpickup\fR(8) daemon does not interact with
25 /* The \fBpickup\fR(8) daemon is moderately security sensitive. It runs
26 /* with fixed low privilege and can run in a chrooted environment.
27 /* However, the program reads files from potentially hostile users.
28 /* The \fBpickup\fR(8) daemon opens no files for writing, is careful about
29 /* what files it opens for reading, and does not actually touch any data
30 /* that is sent to its public service endpoint.
32 /* Problems and transactions are logged to \fBsyslogd\fR(8).
34 /* The \fBpickup\fR(8) daemon copies mail from file to the \fBcleanup\fR(8)
35 /* daemon. It could avoid message copying overhead by sending a file
36 /* descriptor instead of file data, but then the already complex
37 /* \fBcleanup\fR(8) daemon would have to deal with unfiltered user data.
38 /* CONFIGURATION PARAMETERS
41 /* As the \fBpickup\fR(8) daemon is a relatively long-running process, up
42 /* to an hour may pass before a \fBmain.cf\fR change takes effect.
43 /* Use the command "\fBpostfix reload\fR" command to speed up a change.
45 /* The text below provides only a parameter summary. See
46 /* \fBpostconf\fR(5) for more details including examples.
47 /* CONTENT INSPECTION CONTROLS
50 /* .IP "\fBcontent_filter (empty)\fR"
51 /* The name of a mail delivery transport that filters mail after
53 /* .IP "\fBreceive_override_options (empty)\fR"
54 /* Enable or disable recipient validation, built-in content
55 /* filtering, or address mapping.
56 /* MISCELLANEOUS CONTROLS
59 /* .IP "\fBconfig_directory (see 'postconf -d' output)\fR"
60 /* The default location of the Postfix main.cf and master.cf
61 /* configuration files.
62 /* .IP "\fBipc_timeout (3600s)\fR"
63 /* The time limit for sending or receiving information over an internal
64 /* communication channel.
65 /* .IP "\fBline_length_limit (2048)\fR"
66 /* Upon input, long lines are chopped up into pieces of at most
67 /* this length; upon delivery, long lines are reconstructed.
68 /* .IP "\fBmax_idle (100s)\fR"
69 /* The maximum amount of time that an idle Postfix daemon process waits
70 /* for an incoming connection before terminating voluntarily.
71 /* .IP "\fBmax_use (100)\fR"
72 /* The maximal number of incoming connections that a Postfix daemon
73 /* process will service before terminating voluntarily.
74 /* .IP "\fBprocess_id (read-only)\fR"
75 /* The process ID of a Postfix command or daemon process.
76 /* .IP "\fBprocess_name (read-only)\fR"
77 /* The process name of a Postfix command or daemon process.
78 /* .IP "\fBqueue_directory (see 'postconf -d' output)\fR"
79 /* The location of the Postfix top-level queue directory.
80 /* .IP "\fBsyslog_facility (mail)\fR"
81 /* The syslog facility of Postfix logging.
82 /* .IP "\fBsyslog_name (see 'postconf -d' output)\fR"
83 /* The mail system name that is prepended to the process name in syslog
84 /* records, so that "smtpd" becomes, for example, "postfix/smtpd".
86 /* cleanup(8), message canonicalization
87 /* sendmail(1), Sendmail-compatible interface
88 /* postdrop(1), mail posting agent
89 /* postconf(5), configuration parameters
90 /* master(5), generic daemon options
91 /* master(8), process manager
92 /* syslogd(8), system logging
96 /* The Secure Mailer license must be distributed with this software.
99 /* IBM T.J. Watson Research
101 /* Yorktown Heights, NY 10598, USA
104 /* System library. */
106 #include <sys_defs.h>
107 #include <sys/stat.h>
117 /* Utility library. */
120 #include <scan_dir.h>
123 #include <set_ugid.h>
124 #include <safe_open.h>
125 #include <watchdog.h>
126 #include <stringops.h>
128 /* Global library. */
130 #include <mail_queue.h>
131 #include <mail_open_ok.h>
132 #include <mymalloc.h>
133 #include <mail_proto.h>
134 #include <cleanup_user.h>
135 #include <mail_date.h>
136 #include <mail_params.h>
137 #include <mail_conf.h>
139 #include <rec_type.h>
141 #include <input_transp.h>
142 #include <rec_attr_map.h>
143 #include <mail_version.h>
145 /* Single-threaded server skeleton. */
147 #include <mail_server.h>
149 /* Application-specific. */
151 char *var_filter_xport
;
152 char *var_input_transp
;
155 * Structure to bundle a bunch of information about a queue file.
158 char *id
; /* queue file basename */
159 struct stat st
; /* queue file status */
160 char *path
; /* name for open/remove */
161 char *sender
; /* sender address */
165 * What action should be taken after attempting to deliver a message: remove
166 * the file from the maildrop, or leave it alone. The latter is also used
167 * for files that are still being written to.
169 #define REMOVE_MESSAGE_FILE 1
170 #define KEEP_MESSAGE_FILE 2
173 * Transparency: before mail is queued, do we allow address mapping,
174 * automatic bcc, header/body checks?
176 int pickup_input_transp_mask
;
178 /* file_read_error - handle error while reading queue file */
180 static int file_read_error(PICKUP_INFO
*info
, int type
)
182 msg_warn("uid=%ld: unexpected or malformed record type %d",
183 (long) info
->st
.st_uid
, type
);
184 return (REMOVE_MESSAGE_FILE
);
187 /* cleanup_service_error_reason - handle error writing to cleanup service. */
189 static int cleanup_service_error_reason(PICKUP_INFO
*info
, int status
,
194 * XXX If the cleanup server gave a reason, then it was already logged.
195 * Don't bother logging it another time.
198 msg_warn("%s: %s", info
->path
, cleanup_strerror(status
));
199 return ((status
& CLEANUP_STAT_BAD
) ?
200 REMOVE_MESSAGE_FILE
: KEEP_MESSAGE_FILE
);
203 #define cleanup_service_error(info, status) \
204 cleanup_service_error_reason((info), (status), (char *) 0)
206 /* copy_segment - copy a record group */
208 static int copy_segment(VSTREAM
*qfile
, VSTREAM
*cleanup
, PICKUP_INFO
*info
,
209 VSTRING
*buf
, char *expected
)
212 int check_first
= (*expected
== REC_TYPE_CONTENT
[0]);
220 * Limit the input record size. All front-end programs should protect the
221 * mail system against unreasonable inputs. This also requires that we
222 * limit the size of envelope records written by the local posting agent.
224 * Records with named attributes are filtered by postdrop(1).
226 * We must allow PTR records here because of "postsuper -r".
229 if ((type
= rec_get(qfile
, buf
, var_line_limit
)) < 0
230 || strchr(expected
, type
) == 0)
231 return (file_read_error(info
, type
));
233 msg_info("%s: read %c %s", info
->id
, type
, vstring_str(buf
));
234 if (type
== *expected
)
236 if (type
== REC_TYPE_FROM
) {
237 if (info
->sender
== 0)
238 info
->sender
= mystrdup(vstring_str(buf
));
239 /* Compatibility with Postfix < 2.3. */
241 rec_fprintf(cleanup
, REC_TYPE_TIME
, "%ld",
242 (long) info
->st
.st_mtime
);
244 if (type
== REC_TYPE_TIME
)
248 * XXX Workaround: REC_TYPE_FILT (used in envelopes) == REC_TYPE_CONT
249 * (used in message content).
251 * As documented in postsuper(1), ignore content filter record.
253 if (*expected
!= REC_TYPE_CONTENT
[0]) {
254 if (type
== REC_TYPE_FILT
)
255 /* Discard FILTER record after "postsuper -r". */
257 if (type
== REC_TYPE_RDR
)
258 /* Discard REDIRECT record after "postsuper -r". */
261 if (*expected
== REC_TYPE_EXTRACT
[0]) {
262 if (type
== REC_TYPE_RRTO
)
263 /* Discard return-receipt record after "postsuper -r". */
265 if (type
== REC_TYPE_ERTO
)
266 /* Discard errors-to record after "postsuper -r". */
268 if (type
== REC_TYPE_ATTR
) {
269 saved_attr
= mystrdup(vstring_str(buf
));
270 skip_attr
= (split_nameval(saved_attr
,
271 &attr_name
, &attr_value
) == 0
272 && rec_attr_map(attr_name
) == 0);
274 /* Discard other/header/body action after "postsuper -r". */
281 * XXX Force an empty record when the queue file content begins with
282 * whitespace, so that it won't be considered as being part of our
283 * own Received: header. What an ugly Kluge.
286 && (type
== REC_TYPE_NORM
|| type
== REC_TYPE_CONT
)) {
288 if (VSTRING_LEN(buf
) > 0 && IS_SPACE_TAB(vstring_str(buf
)[0]))
289 rec_put(cleanup
, REC_TYPE_NORM
, "", 0);
291 if ((REC_PUT_BUF(cleanup
, type
, buf
)) < 0)
292 return (cleanup_service_error(info
, CLEANUP_STAT_WRITE
));
297 /* pickup_copy - copy message to cleanup service */
299 static int pickup_copy(VSTREAM
*qfile
, VSTREAM
*cleanup
,
300 PICKUP_INFO
*info
, VSTRING
*buf
)
302 time_t now
= time((time_t *) 0);
307 * Protect against time-warped time stamps. Warn about mail that has been
308 * queued for an excessive amount of time. Allow for some time drift with
309 * network clients that mount the maildrop remotely - especially clients
310 * that can't get their daylight savings offsets right.
312 #define DAY_SECONDS 86400
313 #define HOUR_SECONDS 3600
315 if (info
->st
.st_mtime
> now
+ 2 * HOUR_SECONDS
) {
316 msg_warn("%s: message dated %ld seconds into the future",
317 info
->id
, (long) (info
->st
.st_mtime
- now
));
318 info
->st
.st_mtime
= now
;
319 } else if (info
->st
.st_mtime
< now
- DAY_SECONDS
) {
320 msg_warn("%s: message has been queued for %d days",
321 info
->id
, (int) ((now
- info
->st
.st_mtime
) / DAY_SECONDS
));
325 * Add content inspection transport. See also postsuper(1).
327 if (*var_filter_xport
)
328 rec_fprintf(cleanup
, REC_TYPE_FILT
, "%s", var_filter_xport
);
331 * Copy the message envelope segment. Allow only those records that we
332 * expect to see in the envelope section. The envelope segment must
333 * contain an envelope sender address.
335 if ((status
= copy_segment(qfile
, cleanup
, info
, buf
, REC_TYPE_ENVELOPE
)) != 0)
337 if (info
->sender
== 0) {
338 msg_warn("%s: uid=%ld: no envelope sender",
339 info
->id
, (long) info
->st
.st_uid
);
340 return (REMOVE_MESSAGE_FILE
);
344 * For messages belonging to $mail_owner also log the maildrop queue id.
345 * This supports message tracking for mail requeued via "postsuper -r".
347 #define MAIL_IS_REQUEUED(info) \
348 ((info)->st.st_uid == var_owner_uid && ((info)->st.st_mode & S_IROTH) == 0)
350 if (MAIL_IS_REQUEUED(info
)) {
351 msg_info("%s: uid=%d from=<%s> orig_id=%s", info
->id
,
352 (int) info
->st
.st_uid
, info
->sender
,
353 ((name
= strrchr(info
->path
, '/')) != 0 ?
354 name
+ 1 : info
->path
));
356 msg_info("%s: uid=%d from=<%s>", info
->id
,
357 (int) info
->st
.st_uid
, info
->sender
);
361 * Message content segment. Send a dummy message length. Prepend a
362 * Received: header to the message contents. For tracing purposes,
363 * include the message file ownership, without revealing the login name.
365 rec_fputs(cleanup
, REC_TYPE_MESG
, "");
366 rec_fprintf(cleanup
, REC_TYPE_NORM
, "Received: by %s (%s, from userid %ld)",
367 var_myhostname
, var_mail_name
, (long) info
->st
.st_uid
);
368 rec_fprintf(cleanup
, REC_TYPE_NORM
, "\tid %s; %s", info
->id
,
369 mail_date(info
->st
.st_mtime
));
372 * Copy the message content segment. Allow only those records that we
373 * expect to see in the message content section.
375 if ((status
= copy_segment(qfile
, cleanup
, info
, buf
, REC_TYPE_CONTENT
)) != 0)
379 * Send the segment with information extracted from message headers.
380 * Permit a non-empty extracted segment, so that list manager software
381 * can to output recipients after the message, and so that sysadmins can
382 * re-inject messages after a change of configuration.
384 rec_fputs(cleanup
, REC_TYPE_XTRA
, "");
385 if ((status
= copy_segment(qfile
, cleanup
, info
, buf
, REC_TYPE_EXTRACT
)) != 0)
389 * There are no errors. Send the end-of-data marker, and get the cleanup
390 * service completion status. XXX Since the pickup service is unable to
391 * bounce, the cleanup service can report only soft errors here.
393 rec_fputs(cleanup
, REC_TYPE_END
, "");
394 if (attr_scan(cleanup
, ATTR_FLAG_MISSING
,
395 ATTR_TYPE_INT
, MAIL_ATTR_STATUS
, &status
,
396 ATTR_TYPE_STR
, MAIL_ATTR_WHY
, buf
,
398 return (cleanup_service_error(info
, CLEANUP_STAT_WRITE
));
401 * Depending on the cleanup service completion status, delete the message
402 * file, or try again later. Bounces are dealt with by the cleanup
403 * service itself. The master process wakes up the cleanup service every
407 return (cleanup_service_error_reason(info
, status
, vstring_str(buf
)));
409 return (REMOVE_MESSAGE_FILE
);
413 /* pickup_file - initialize for file copy and cleanup */
415 static int pickup_file(PICKUP_INFO
*info
)
417 VSTRING
*buf
= vstring_alloc(100);
424 * Open the submitted file. If we cannot open it, and we're not having a
425 * file descriptor leak problem, delete the submitted file, so that we
426 * won't keep complaining about the same file again and again. XXX
427 * Perhaps we should save "bad" files elsewhere for further inspection.
428 * XXX How can we delete a file when open() fails with ENOENT?
430 qfile
= safe_open(info
->path
, O_RDONLY
| O_NONBLOCK
, 0,
431 (struct stat
*) 0, -1, -1, buf
);
434 msg_warn("open input file %s: %s", info
->path
, vstring_str(buf
));
437 msg_warn("if this file was created by Postfix < 1.1, then you may have to chmod a+r %s/%s",
438 var_queue_dir
, info
->path
);
439 return (errno
== EACCES
? KEEP_MESSAGE_FILE
: REMOVE_MESSAGE_FILE
);
443 * Contact the cleanup service and read the queue ID that it has
444 * allocated. In case of trouble, request that the cleanup service
445 * bounces its copy of the message. because the original input file is
446 * not readable by the bounce service.
448 * If mail is re-injected with "postsuper -r", disable Milter applications.
449 * If they were run before the mail was queued then there is no need to
450 * run them again. Moreover, the queue file does not contain enough
451 * information to reproduce the exact same SMTP events and Sendmail
452 * macros that Milters received when the mail originally arrived in
455 * The actual message copying code is in a separate routine, so that it is
456 * easier to implement the many possible error exits without forgetting
457 * to close files, or to release memory.
460 input_transp_cleanup(CLEANUP_FLAG_BOUNCE
| CLEANUP_FLAG_MASK_EXTERNAL
,
461 pickup_input_transp_mask
);
462 /* As documented in postsuper(1). */
463 if (MAIL_IS_REQUEUED(info
))
464 cleanup_flags
&= ~CLEANUP_FLAG_MILTER
;
466 cleanup
= mail_connect_wait(MAIL_CLASS_PUBLIC
, var_cleanup_service
);
467 if (attr_scan(cleanup
, ATTR_FLAG_STRICT
,
468 ATTR_TYPE_STR
, MAIL_ATTR_QUEUEID
, buf
,
470 || attr_print(cleanup
, ATTR_FLAG_NONE
,
471 ATTR_TYPE_INT
, MAIL_ATTR_FLAGS
, cleanup_flags
,
472 ATTR_TYPE_END
) != 0) {
473 status
= KEEP_MESSAGE_FILE
;
475 info
->id
= mystrdup(vstring_str(buf
));
476 status
= pickup_copy(qfile
, cleanup
, info
, buf
);
478 vstream_fclose(qfile
);
479 vstream_fclose(cleanup
);
484 /* pickup_init - init info structure */
486 static void pickup_init(PICKUP_INFO
*info
)
493 /* pickup_free - wipe info structure */
495 static void pickup_free(PICKUP_INFO
*info
)
497 #define SAFE_FREE(x) { if (x) myfree(x); }
500 SAFE_FREE(info
->path
);
501 SAFE_FREE(info
->sender
);
504 /* pickup_service - service client */
506 static void pickup_service(char *unused_buf
, int unused_len
,
507 char *unused_service
, char **argv
)
517 * Sanity check. This service takes no command-line arguments.
520 msg_fatal("unexpected command-line argument: %s", argv
[0]);
523 * Skip over things that we don't want to open, such as files that are
524 * still being written, or garbage. Leave it up to the sysadmin to remove
525 * garbage. Keep scanning the queue directory until we stop removing
528 * When we find a file, stroke the watchdog so that it will not bark while
529 * some application is keeping us busy by injecting lots of mail into the
530 * maildrop directory.
532 queue_name
= MAIL_QUEUE_MAILDROP
; /* XXX should be a list */
535 scan
= scan_dir_open(queue_name
);
536 while ((id
= scan_dir_next(scan
)) != 0) {
537 if (mail_open_ok(queue_name
, id
, &info
.st
, &path
) == MAIL_OPEN_YES
) {
539 info
.path
= mystrdup(path
);
541 if (pickup_file(&info
) == REMOVE_MESSAGE_FILE
) {
542 if (REMOVE(info
.path
))
543 msg_warn("remove %s: %m", info
.path
);
550 scan_dir_close(scan
);
551 } while (file_count
);
554 /* post_jail_init - drop privileges */
556 static void post_jail_init(char *unused_name
, char **unused_argv
)
560 * In case master.cf was not updated for unprivileged service.
562 if (getuid() != var_owner_uid
)
563 set_ugid(var_owner_uid
, var_owner_gid
);
566 * Initialize the receive transparency options: do we want unknown
567 * recipient checks, do we want address mapping.
569 pickup_input_transp_mask
=
570 input_transp_mask(VAR_INPUT_TRANSP
, var_input_transp
);
573 MAIL_VERSION_STAMP_DECLARE
;
575 /* main - pass control to the multi-threaded server skeleton */
577 int main(int argc
, char **argv
)
579 static const CONFIG_STR_TABLE str_table
[] = {
580 VAR_FILTER_XPORT
, DEF_FILTER_XPORT
, &var_filter_xport
, 0, 0,
581 VAR_INPUT_TRANSP
, DEF_INPUT_TRANSP
, &var_input_transp
, 0, 0,
586 * Fingerprint executables and core dumps.
588 MAIL_VERSION_STAMP_ALLOCATE
;
591 * Use the multi-threaded skeleton, because no-one else should be
592 * monitoring our service socket while this process runs.
594 * XXX The default watchdog timeout for trigger servers is 1000s, while the
595 * cleanup server watchdog timeout is $daemon_timeout (i.e. several
596 * hours). We override the default 1000s timeout to avoid problems with
597 * slow mail submission. The real problem is of course that the
598 * single-threaded pickup server is not a good solution for mail
601 trigger_server_main(argc
, argv
, pickup_service
,
602 MAIL_SERVER_STR_TABLE
, str_table
,
603 MAIL_SERVER_POST_INIT
, post_jail_init
,
604 MAIL_SERVER_SOLITARY
,
605 MAIL_SERVER_WATCHDOG
, &var_daemon_timeout
,