7 /* Postfix delivery to external command
9 /* \fBpipe\fR [generic Postfix daemon options] command_attributes...
11 /* The \fBpipe\fR(8) daemon processes requests from the Postfix queue
12 /* manager to deliver messages to external commands.
13 /* This program expects to be run from the \fBmaster\fR(8) process
16 /* Message attributes such as sender address, recipient address and
17 /* next-hop host name can be specified as command-line macros that are
18 /* expanded before the external command is executed.
20 /* The \fBpipe\fR(8) daemon updates queue files and marks recipients
21 /* as finished, or it informs the queue manager that delivery should
22 /* be tried again at a later time. Delivery status reports are sent
23 /* to the \fBbounce\fR(8), \fBdefer\fR(8) or \fBtrace\fR(8) daemon as
25 /* SINGLE-RECIPIENT DELIVERY
28 /* Some destinations cannot handle more than one recipient per
29 /* delivery request. Examples are pagers or fax machines.
30 /* In addition, multi-recipient delivery is undesirable when
31 /* prepending a \fBDelivered-to:\fR or \fBX-Original-To:\fR
34 /* To prevent Postfix from sending multiple recipients per delivery
38 /* \fItransport\fB_destination_recipient_limit = 1\fR
41 /* in the Postfix \fBmain.cf\fR file, where \fItransport\fR
42 /* is the name in the first column of the Postfix \fBmaster.cf\fR
43 /* entry for the pipe-based delivery transport.
44 /* COMMAND ATTRIBUTE SYNTAX
47 /* The external command attributes are given in the \fBmaster.cf\fR
48 /* file at the end of a service definition. The syntax is as follows:
49 /* .IP "\fBchroot=\fIpathname\fR (optional)"
50 /* Change the process root directory and working directory to
51 /* the named directory. This happens before switching to the
52 /* privileges specified with the \fBuser\fR attribute, and
53 /* before executing the optional \fBdirectory=\fIpathname\fR
54 /* directive. Delivery is deferred in case of failure.
56 /* This feature is available as of Postfix 2.3.
57 /* .IP "\fBdirectory=\fIpathname\fR (optional)"
58 /* Change to the named directory before executing the external command.
59 /* The directory must be accessible for the user specified with the
60 /* \fBuser\fR attribute (see below).
61 /* The default working directory is \fB$queue_directory\fR.
62 /* Delivery is deferred in case of failure.
64 /* This feature is available as of Postfix 2.2.
65 /* .IP "\fBeol=\fIstring\fR (optional, default: \fB\en\fR)"
66 /* The output record delimiter. Typically one would use either
67 /* \fB\er\en\fR or \fB\en\fR. The usual C-style backslash escape
68 /* sequences are recognized: \fB\ea \eb \ef \en \er \et \ev
69 /* \e\fIddd\fR (up to three octal digits) and \fB\e\e\fR.
70 /* .IP "\fBflags=BDFORXhqu.>\fR (optional)"
71 /* Optional message processing flags. By default, a message is
75 /* Append a blank line at the end of each message. This is required
76 /* by some mail user agents that recognize "\fBFrom \fR" lines only
77 /* when preceded by a blank line.
79 /* Prepend a "\fBDelivered-To: \fIrecipient\fR" message header with the
80 /* envelope recipient address. Note: for this to work, the
81 /* \fItransport\fB_destination_recipient_limit\fR must be 1
82 /* (see SINGLE-RECIPIENT DELIVERY above for details).
84 /* The \fBD\fR flag also enforces loop detection (Postfix 2.5 and later):
85 /* if a message already contains a \fBDelivered-To:\fR header
86 /* with the same recipient address, then the message is
87 /* returned as undeliverable. The address comparison is case
90 /* This feature is available as of Postfix 2.0.
92 /* Prepend a "\fBFrom \fIsender time_stamp\fR" envelope header to
93 /* the message content.
94 /* This is expected by, for example, \fBUUCP\fR software.
96 /* Prepend an "\fBX-Original-To: \fIrecipient\fR" message header
97 /* with the recipient address as given to Postfix. Note: for this to
98 /* work, the \fItransport\fB_destination_recipient_limit\fR must be 1
99 /* (see SINGLE-RECIPIENT DELIVERY above for details).
101 /* This feature is available as of Postfix 2.0.
103 /* Prepend a \fBReturn-Path:\fR message header with the envelope sender
106 /* Indicate that the external command performs final delivery.
107 /* This flag affects the status reported in "success" DSN
108 /* (delivery status notification) messages, and changes it
109 /* from "relayed" into "delivered".
111 /* This feature is available as of Postfix 2.5.
113 /* Fold the command-line \fB$original_recipient\fR and
114 /* \fB$recipient\fR address domain part
115 /* (text to the right of the right-most \fB@\fR character) to
116 /* lower case; fold the entire command-line \fB$domain\fR and
117 /* \fB$nexthop\fR host or domain information to lower case.
118 /* This is recommended for delivery via \fBUUCP\fR.
120 /* Quote white space and other special characters in the command-line
121 /* \fB$sender\fR, \fB$original_recipient\fR and \fB$recipient\fR
122 /* address localparts (text to the
123 /* left of the right-most \fB@\fR character), according to an 8-bit
124 /* transparent version of RFC 822.
125 /* This is recommended for delivery via \fBUUCP\fR or \fBBSMTP\fR.
127 /* The result is compatible with the address parsing of command-line
128 /* recipients by the Postfix \fBsendmail\fR(1) mail submission command.
130 /* The \fBq\fR flag affects only entire addresses, not the partial
131 /* address information from the \fB$user\fR, \fB$extension\fR or
132 /* \fB$mailbox\fR command-line macros.
134 /* Fold the command-line \fB$original_recipient\fR and
135 /* \fB$recipient\fR address localpart (text to
136 /* the left of the right-most \fB@\fR character) to lower case.
137 /* This is recommended for delivery via \fBUUCP\fR.
139 /* Prepend "\fB.\fR" to lines starting with "\fB.\fR". This is needed
140 /* by, for example, \fBBSMTP\fR software.
142 /* Prepend "\fB>\fR" to lines starting with "\fBFrom \fR". This is expected
143 /* by, for example, \fBUUCP\fR software.
145 /* .IP "\fBnull_sender\fR=\fIreplacement\fR (default: MAILER-DAEMON)"
146 /* Replace the null sender address (typically used for delivery
147 /* status notifications) with the specified text
148 /* when expanding the \fB$sender\fR command-line macro, and
149 /* when generating a From_ or Return-Path: message header.
151 /* If the null sender replacement text is a non-empty string
152 /* then it is affected by the \fBq\fR flag for address quoting
153 /* in command-line arguments.
155 /* The null sender replacement text may be empty; this form
156 /* is recommended for content filters that feed mail back into
157 /* Postfix. The empty sender address is not affected by the
158 /* \fBq\fR flag for address quoting in command-line arguments.
160 /* Caution: a null sender address is easily mis-parsed by
161 /* naive software. For example, when the \fBpipe\fR(8) daemon
162 /* executes a command such as:
165 /* \fIWrong\fR: command -f$sender -- $recipient
168 /* the command will mis-parse the -f option value when the
169 /* sender address is a null string. For correct parsing,
170 /* specify \fB$sender\fR as an argument by itself:
173 /* \fIRight\fR: command -f $sender -- $recipient
176 /* This feature is available as of Postfix 2.3.
177 /* .IP "\fBsize\fR=\fIsize_limit\fR (optional)"
178 /* Don't deliver messages that exceed this size limit (in
179 /* bytes); return them to the sender instead.
180 /* .IP "\fBuser\fR=\fIusername\fR (required)"
181 /* .IP "\fBuser\fR=\fIusername\fR:\fIgroupname\fR"
182 /* Execute the external command with the rights of the
183 /* specified \fIusername\fR. The software refuses to execute
184 /* commands with root privileges, or with the privileges of the
185 /* mail system owner. If \fIgroupname\fR is specified, the
186 /* corresponding group ID is used instead of the group ID of
188 /* .IP "\fBargv\fR=\fIcommand\fR... (required)"
189 /* The command to be executed. This must be specified as the
190 /* last command attribute.
191 /* The command is executed directly, i.e. without interpretation of
192 /* shell meta characters by a shell command interpreter.
194 /* In the command argument vector, the following macros are recognized
195 /* and replaced with corresponding information from the Postfix queue
196 /* manager delivery request.
198 /* In addition to the form ${\fIname\fR}, the forms $\fIname\fR and
199 /* $(\fIname\fR) are also recognized. Specify \fB$$\fR where a single
200 /* \fB$\fR is wanted.
202 /* .IP \fB${\fBclient_address\fR}\fR
203 /* This macro expands to the remote client network address.
205 /* This feature is available as of Postfix 2.2.
206 /* .IP \fB${\fBclient_helo\fR}\fR
207 /* This macro expands to the remote client HELO command parameter.
209 /* This feature is available as of Postfix 2.2.
210 /* .IP \fB${\fBclient_hostname\fR}\fR
211 /* This macro expands to the remote client hostname.
213 /* This feature is available as of Postfix 2.2.
214 /* .IP \fB${\fBclient_port\fR}\fR
215 /* This macro expands to the remote client TCP port number.
217 /* This feature is available as of Postfix 2.5.
218 /* .IP \fB${\fBclient_protocol\fR}\fR
219 /* This macro expands to the remote client protocol.
221 /* This feature is available as of Postfix 2.2.
222 /* .IP \fB${\fBdomain\fR}\fR
223 /* This macro expands to the domain portion of the recipient
224 /* address. For example, with an address \fIuser+foo@domain\fR
225 /* the domain is \fIdomain\fR.
227 /* This information is modified by the \fBh\fR flag for case folding.
229 /* This feature is available as of Postfix 2.5.
230 /* .IP \fB${\fBextension\fR}\fR
231 /* This macro expands to the extension part of a recipient address.
232 /* For example, with an address \fIuser+foo@domain\fR the extension is
235 /* A command-line argument that contains \fB${\fBextension\fR}\fR expands
236 /* into as many command-line arguments as there are recipients.
238 /* This information is modified by the \fBu\fR flag for case folding.
239 /* .IP \fB${\fBmailbox\fR}\fR
240 /* This macro expands to the complete local part of a recipient address.
241 /* For example, with an address \fIuser+foo@domain\fR the mailbox is
244 /* A command-line argument that contains \fB${\fBmailbox\fR}\fR
245 /* expands to as many command-line arguments as there are recipients.
247 /* This information is modified by the \fBu\fR flag for case folding.
248 /* .IP \fB${\fBnexthop\fR}\fR
249 /* This macro expands to the next-hop hostname.
251 /* This information is modified by the \fBh\fR flag for case folding.
252 /* .IP \fB${\fBoriginal_recipient\fR}\fR
253 /* This macro expands to the complete recipient address before any
254 /* address rewriting or aliasing.
256 /* A command-line argument that contains
257 /* \fB${\fBoriginal_recipient\fR}\fR expands to as many
258 /* command-line arguments as there are recipients.
260 /* This information is modified by the \fBhqu\fR flags for quoting
263 /* This feature is available as of Postfix 2.5.
264 /* .IP \fB${\fBrecipient\fR}\fR
265 /* This macro expands to the complete recipient address.
267 /* A command-line argument that contains \fB${\fBrecipient\fR}\fR
268 /* expands to as many command-line arguments as there are recipients.
270 /* This information is modified by the \fBhqu\fR flags for quoting
272 /* .IP \fB${\fBsasl_method\fR}\fR
273 /* This macro expands to the name of the SASL authentication
274 /* mechanism in the AUTH command when the Postfix SMTP server
275 /* received the message.
277 /* This feature is available as of Postfix 2.2.
278 /* .IP \fB${\fBsasl_sender\fR}\fR
279 /* This macro expands to the SASL sender name (i.e. the original
280 /* submitter as per RFC 4954) in the MAIL FROM command when
281 /* the Postfix SMTP server received the message.
283 /* This feature is available as of Postfix 2.2.
284 /* .IP \fB${\fBsasl_username\fR}\fR
285 /* This macro expands to the SASL user name in the AUTH command
286 /* when the Postfix SMTP server received the message.
288 /* This feature is available as of Postfix 2.2.
289 /* .IP \fB${\fBsender\fR}\fR
290 /* This macro expands to the envelope sender address. By default,
291 /* the null sender address expands to MAILER-DAEMON; this can
292 /* be changed with the \fBnull_sender\fR attribute, as described
295 /* This information is modified by the \fBq\fR flag for quoting.
296 /* .IP \fB${\fBsize\fR}\fR
297 /* This macro expands to Postfix's idea of the message size, which
298 /* is an approximation of the size of the message as delivered.
299 /* .IP \fB${\fBuser\fR}\fR
300 /* This macro expands to the username part of a recipient address.
301 /* For example, with an address \fIuser+foo@domain\fR the username
302 /* part is \fIuser\fR.
304 /* A command-line argument that contains \fB${\fBuser\fR}\fR expands
305 /* into as many command-line arguments as there are recipients.
307 /* This information is modified by the \fBu\fR flag for case folding.
310 /* RFC 3463 (Enhanced status codes)
312 /* Command exit status codes are expected to
313 /* follow the conventions defined in <\fBsysexits.h\fR>.
314 /* Exit status 0 means normal successful completion.
316 /* Postfix version 2.3 and later support RFC 3463-style enhanced
317 /* status codes. If a command terminates with a non-zero exit
318 /* status, and the command output begins with an enhanced
319 /* status code, this status code takes precedence over the
320 /* non-zero exit status.
322 /* Problems and transactions are logged to \fBsyslogd\fR(8).
323 /* Corrupted message files are marked so that the queue manager
324 /* can move them to the \fBcorrupt\fR queue for further inspection.
328 /* This program needs a dual personality 1) to access the private
329 /* Postfix queue and IPC mechanisms, and 2) to execute external
330 /* commands as the specified user. It is therefore security sensitive.
331 /* CONFIGURATION PARAMETERS
334 /* Changes to \fBmain.cf\fR are picked up automatically as \fBpipe\fR(8)
335 /* processes run for only a limited amount of time. Use the command
336 /* "\fBpostfix reload\fR" to speed up a change.
338 /* The text below provides only a parameter summary. See
339 /* \fBpostconf\fR(5) for more details including examples.
340 /* RESOURCE AND RATE CONTROLS
343 /* In the text below, \fItransport\fR is the first field in a
344 /* \fBmaster.cf\fR entry.
345 /* .IP "\fItransport\fB_destination_concurrency_limit ($default_destination_concurrency_limit)\fR"
346 /* Limit the number of parallel deliveries to the same destination,
347 /* for delivery via the named \fItransport\fR.
348 /* The limit is enforced by the Postfix queue manager.
349 /* .IP "\fItransport\fB_destination_recipient_limit ($default_destination_recipient_limit)\fR"
350 /* Limit the number of recipients per message delivery, for delivery
351 /* via the named \fItransport\fR.
352 /* The limit is enforced by the Postfix queue manager.
353 /* .IP "\fItransport\fB_time_limit ($command_time_limit)\fR"
354 /* Limit the time for delivery to external command, for delivery via
355 /* the named \fItransport\fR.
356 /* The limit is enforced by the pipe delivery agent.
358 /* Postfix 2.4 and later support a suffix that specifies the
359 /* time unit: s (seconds), m (minutes), h (hours), d (days),
360 /* w (weeks). The default time unit is seconds.
361 /* MISCELLANEOUS CONTROLS
364 /* .IP "\fBconfig_directory (see 'postconf -d' output)\fR"
365 /* The default location of the Postfix main.cf and master.cf
366 /* configuration files.
367 /* .IP "\fBdaemon_timeout (18000s)\fR"
368 /* How much time a Postfix daemon process may take to handle a
369 /* request before it is terminated by a built-in watchdog timer.
370 /* .IP "\fBdelay_logging_resolution_limit (2)\fR"
371 /* The maximal number of digits after the decimal point when logging
372 /* sub-second delay values.
373 /* .IP "\fBexport_environment (see 'postconf -d' output)\fR"
374 /* The list of environment variables that a Postfix process will export
375 /* to non-Postfix processes.
376 /* .IP "\fBipc_timeout (3600s)\fR"
377 /* The time limit for sending or receiving information over an internal
378 /* communication channel.
379 /* .IP "\fBmail_owner (postfix)\fR"
380 /* The UNIX system account that owns the Postfix queue and most Postfix
382 /* .IP "\fBmax_idle (100s)\fR"
383 /* The maximum amount of time that an idle Postfix daemon process waits
384 /* for an incoming connection before terminating voluntarily.
385 /* .IP "\fBmax_use (100)\fR"
386 /* The maximal number of incoming connections that a Postfix daemon
387 /* process will service before terminating voluntarily.
388 /* .IP "\fBprocess_id (read-only)\fR"
389 /* The process ID of a Postfix command or daemon process.
390 /* .IP "\fBprocess_name (read-only)\fR"
391 /* The process name of a Postfix command or daemon process.
392 /* .IP "\fBqueue_directory (see 'postconf -d' output)\fR"
393 /* The location of the Postfix top-level queue directory.
394 /* .IP "\fBrecipient_delimiter (empty)\fR"
395 /* The separator between user names and address extensions (user+foo).
396 /* .IP "\fBsyslog_facility (mail)\fR"
397 /* The syslog facility of Postfix logging.
398 /* .IP "\fBsyslog_name (see 'postconf -d' output)\fR"
399 /* The mail system name that is prepended to the process name in syslog
400 /* records, so that "smtpd" becomes, for example, "postfix/smtpd".
402 /* qmgr(8), queue manager
403 /* bounce(8), delivery status reports
404 /* postconf(5), configuration parameters
405 /* master(5), generic daemon options
406 /* master(8), process manager
407 /* syslogd(8), system logging
411 /* The Secure Mailer license must be distributed with this software.
414 /* IBM T.J. Watson Research
416 /* Yorktown Heights, NY 10598, USA
419 /* System library. */
421 #include <sys_defs.h>
430 #ifdef STRCASECMP_IN_STRINGS_H
434 /* Utility library. */
443 #include <mymalloc.h>
444 #include <mac_parse.h>
445 #include <set_eugid.h>
446 #include <split_at.h>
447 #include <stringops.h>
449 /* Global library. */
451 #include <recipient_list.h>
452 #include <deliver_request.h>
453 #include <mail_params.h>
454 #include <mail_version.h>
455 #include <mail_conf.h>
458 #include <deliver_completed.h>
460 #include <pipe_command.h>
461 #include <mail_copy.h>
462 #include <mail_addr.h>
463 #include <canon_addr.h>
464 #include <split_addr.h>
466 #include <quote_822_local.h>
467 #include <flush_clnt.h>
468 #include <dsn_util.h>
470 #include <sys_exits.h>
471 #include <delivered_hdr.h>
472 #include <fold_addr.h>
474 /* Single server skeleton. */
476 #include <mail_server.h>
478 /* Application-specific. */
481 * The mini symbol table name and keys used for expanding macros in
482 * command-line arguments.
484 * XXX Update the parse_callback() routine when something gets added here,
485 * even when the macro is not recipient dependent.
487 #define PIPE_DICT_TABLE "pipe_command" /* table name */
488 #define PIPE_DICT_NEXTHOP "nexthop" /* key */
489 #define PIPE_DICT_RCPT "recipient" /* key */
490 #define PIPE_DICT_ORIG_RCPT "original_recipient" /* key */
491 #define PIPE_DICT_SENDER "sender"/* key */
492 #define PIPE_DICT_USER "user" /* key */
493 #define PIPE_DICT_EXTENSION "extension" /* key */
494 #define PIPE_DICT_MAILBOX "mailbox" /* key */
495 #define PIPE_DICT_DOMAIN "domain"/* key */
496 #define PIPE_DICT_SIZE "size" /* key */
497 #define PIPE_DICT_CLIENT_ADDR "client_address" /* key */
498 #define PIPE_DICT_CLIENT_NAME "client_hostname" /* key */
499 #define PIPE_DICT_CLIENT_PORT "client_port" /* key */
500 #define PIPE_DICT_CLIENT_PROTO "client_protocol" /* key */
501 #define PIPE_DICT_CLIENT_HELO "client_helo" /* key */
502 #define PIPE_DICT_SASL_METHOD "sasl_method" /* key */
503 #define PIPE_DICT_SASL_USERNAME "sasl_username" /* key */
504 #define PIPE_DICT_SASL_SENDER "sasl_sender" /* key */
507 * Flags used to pass back the type of special parameter found by
510 #define PIPE_FLAG_RCPT (1<<0)
511 #define PIPE_FLAG_USER (1<<1)
512 #define PIPE_FLAG_EXTENSION (1<<2)
513 #define PIPE_FLAG_MAILBOX (1<<3)
514 #define PIPE_FLAG_DOMAIN (1<<4)
515 #define PIPE_FLAG_ORIG_RCPT (1<<5)
518 * Additional flags. These are colocated with mail_copy() flags. Allow some
519 * space for extension of the mail_copy() interface.
521 #define PIPE_OPT_FOLD_BASE (16)
522 #define PIPE_OPT_FOLD_USER (FOLD_ADDR_USER << PIPE_OPT_FOLD_BASE)
523 #define PIPE_OPT_FOLD_HOST (FOLD_ADDR_HOST << PIPE_OPT_FOLD_BASE)
524 #define PIPE_OPT_QUOTE_LOCAL (1 << (PIPE_OPT_FOLD_BASE + 2))
525 #define PIPE_OPT_FINAL_DELIVERY (1 << (PIPE_OPT_FOLD_BASE + 3))
527 #define PIPE_OPT_FOLD_ALL (FOLD_ADDR_ALL << PIPE_OPT_FOLD_BASE)
528 #define PIPE_OPT_FOLD_FLAGS(f) \
529 (((f) & PIPE_OPT_FOLD_ALL) >> PIPE_OPT_FOLD_BASE)
532 * Tunable parameters. Values are taken from the config file, after
533 * prepending the service name to _name, and so on.
535 int var_command_maxtime
; /* system-wide */
538 * For convenience. Instead of passing around lists of parameters, bundle
539 * them up in convenient structures.
543 * Structure for service-specific configuration parameters.
546 int time_limit
; /* per-service time limit */
550 * Structure for command-line parameters.
553 char **command
; /* argument vector */
554 uid_t uid
; /* command privileges */
555 gid_t gid
; /* command privileges */
556 int flags
; /* mail_copy() flags */
557 char *exec_dir
; /* working directory */
558 char *chroot_dir
; /* chroot directory */
559 VSTRING
*eol
; /* output record delimiter */
560 VSTRING
*null_sender
; /* null sender expansion */
561 off_t size_limit
; /* max size in bytes we will accept */
565 * Structure for command-line parameter macro expansion.
568 const char *service
; /* for warnings */
569 int expand_flag
; /* callback result */
573 * Silly little macros.
575 #define STR vstring_str
577 /* parse_callback - callback for mac_parse() */
579 static int parse_callback(int type
, VSTRING
*buf
, char *context
)
581 PIPE_STATE
*state
= (PIPE_STATE
*) context
;
586 static struct cmd_flags cmd_flags
[] = {
587 PIPE_DICT_NEXTHOP
, 0,
588 PIPE_DICT_RCPT
, PIPE_FLAG_RCPT
,
589 PIPE_DICT_ORIG_RCPT
, PIPE_FLAG_ORIG_RCPT
,
591 PIPE_DICT_USER
, PIPE_FLAG_USER
,
592 PIPE_DICT_EXTENSION
, PIPE_FLAG_EXTENSION
,
593 PIPE_DICT_MAILBOX
, PIPE_FLAG_MAILBOX
,
594 PIPE_DICT_DOMAIN
, PIPE_FLAG_DOMAIN
,
596 PIPE_DICT_CLIENT_ADDR
, 0,
597 PIPE_DICT_CLIENT_NAME
, 0,
598 PIPE_DICT_CLIENT_PORT
, 0,
599 PIPE_DICT_CLIENT_PROTO
, 0,
600 PIPE_DICT_CLIENT_HELO
, 0,
601 PIPE_DICT_SASL_METHOD
, 0,
602 PIPE_DICT_SASL_USERNAME
, 0,
603 PIPE_DICT_SASL_SENDER
, 0,
609 * See if this command-line argument references a special macro.
611 if (type
== MAC_PARSE_VARNAME
) {
612 for (p
= cmd_flags
; /* see below */ ; p
++) {
614 msg_warn("file %s/%s: service %s: unknown macro name: \"%s\"",
615 var_config_dir
, MASTER_CONF_FILE
,
616 state
->service
, vstring_str(buf
));
617 return (MAC_PARSE_ERROR
);
618 } else if (strcmp(vstring_str(buf
), p
->name
) == 0) {
619 state
->expand_flag
|= p
->flags
;
627 /* morph_recipient - morph a recipient address */
629 static void morph_recipient(VSTRING
*buf
, const char *address
, int flags
)
633 * Quote the recipient address as appropriate.
635 if (flags
& PIPE_OPT_QUOTE_LOCAL
)
636 quote_822_local(buf
, address
);
638 vstring_strcpy(buf
, address
);
641 * Fold the recipient address as appropriate.
643 if (flags
& PIPE_OPT_FOLD_ALL
)
644 fold_addr(STR(buf
), PIPE_OPT_FOLD_FLAGS(flags
));
647 /* expand_argv - expand macros in the argument vector */
649 static ARGV
*expand_argv(const char *service
, char **argv
,
650 RECIPIENT_LIST
*rcpt_list
, int flags
)
652 VSTRING
*buf
= vstring_alloc(100);
661 * This appears to be simple operation (replace $name by its expansion).
662 * However, it becomes complex because a command-line argument that
663 * references $recipient must expand to as many command-line arguments as
664 * there are recipients (that's wat programs called by sendmail expect).
665 * So we parse each command-line argument, and depending on what we find,
666 * we either expand the argument just once, or we expand it once for each
667 * recipient. In either case we end up parsing the command-line argument
668 * twice. The amount of CPU time wasted will be negligible.
670 * Note: we can't use recursive macro expansion here, because recursion
671 * would screw up mail addresses that contain $ characters.
674 #define EARLY_RETURN(x) { argv_free(result); vstring_free(buf); return (x); }
676 result
= argv_alloc(1);
677 for (cpp
= argv
; *cpp
; cpp
++) {
678 state
.service
= service
;
679 state
.expand_flag
= 0;
680 if (mac_parse(*cpp
, parse_callback
, (char *) &state
) & MAC_PARSE_ERROR
)
682 if (state
.expand_flag
== 0) { /* no $recipient etc. */
683 argv_add(result
, dict_eval(PIPE_DICT_TABLE
, *cpp
, NO
), ARGV_END
);
684 } else { /* contains $recipient etc. */
685 for (i
= 0; i
< rcpt_list
->len
; i
++) {
688 * This argument contains $recipient.
690 if (state
.expand_flag
& PIPE_FLAG_RCPT
) {
691 morph_recipient(buf
, rcpt_list
->info
[i
].address
, flags
);
692 dict_update(PIPE_DICT_TABLE
, PIPE_DICT_RCPT
, STR(buf
));
696 * This argument contains $original_recipient.
698 if (state
.expand_flag
& PIPE_FLAG_ORIG_RCPT
) {
699 morph_recipient(buf
, rcpt_list
->info
[i
].orig_addr
, flags
);
700 dict_update(PIPE_DICT_TABLE
, PIPE_DICT_ORIG_RCPT
, STR(buf
));
704 * This argument contains $user. Extract the plain user name.
705 * Either anything to the left of the extension delimiter or,
706 * in absence of the latter, anything to the left of the
709 * Beware: if the user name is blank (e.g. +user@host), the
710 * argument is suppressed. This is necessary to allow for
711 * cyrus bulletin-board (global mailbox) delivery. XXX But,
712 * skipping empty user parts will also prevent other
713 * expansions of this specific command-line argument.
715 if (state
.expand_flag
& PIPE_FLAG_USER
) {
716 morph_recipient(buf
, rcpt_list
->info
[i
].address
,
717 flags
& PIPE_OPT_FOLD_ALL
);
718 if (split_at_right(STR(buf
), '@') == 0)
719 msg_warn("no @ in recipient address: %s",
720 rcpt_list
->info
[i
].address
);
722 split_addr(STR(buf
), *var_rcpt_delim
);
725 dict_update(PIPE_DICT_TABLE
, PIPE_DICT_USER
, STR(buf
));
729 * This argument contains $extension. Extract the recipient
730 * extension: anything between the leftmost extension
731 * delimiter and the rightmost @. The extension may be blank.
733 if (state
.expand_flag
& PIPE_FLAG_EXTENSION
) {
734 morph_recipient(buf
, rcpt_list
->info
[i
].address
,
735 flags
& PIPE_OPT_FOLD_ALL
);
736 if (split_at_right(STR(buf
), '@') == 0)
737 msg_warn("no @ in recipient address: %s",
738 rcpt_list
->info
[i
].address
);
739 if (*var_rcpt_delim
== 0
740 || (ext
= split_addr(STR(buf
), *var_rcpt_delim
)) == 0)
741 ext
= ""; /* insert null arg */
742 dict_update(PIPE_DICT_TABLE
, PIPE_DICT_EXTENSION
, ext
);
746 * This argument contains $mailbox. Extract the mailbox name:
747 * anything to the left of the rightmost @.
749 if (state
.expand_flag
& PIPE_FLAG_MAILBOX
) {
750 morph_recipient(buf
, rcpt_list
->info
[i
].address
,
751 flags
& PIPE_OPT_FOLD_ALL
);
752 if (split_at_right(STR(buf
), '@') == 0)
753 msg_warn("no @ in recipient address: %s",
754 rcpt_list
->info
[i
].address
);
755 dict_update(PIPE_DICT_TABLE
, PIPE_DICT_MAILBOX
, STR(buf
));
759 * This argument contains $domain. Extract the domain name:
760 * anything to the right of the rightmost @.
762 if (state
.expand_flag
& PIPE_FLAG_DOMAIN
) {
763 morph_recipient(buf
, rcpt_list
->info
[i
].address
,
764 flags
& PIPE_OPT_FOLD_ALL
);
765 dom
= split_at_right(STR(buf
), '@');
767 msg_warn("no @ in recipient address: %s",
768 rcpt_list
->info
[i
].address
);
769 dom
= ""; /* insert null arg */
771 dict_update(PIPE_DICT_TABLE
, PIPE_DICT_DOMAIN
, dom
);
777 argv_add(result
, dict_eval(PIPE_DICT_TABLE
, *cpp
, NO
), ARGV_END
);
781 argv_terminate(result
);
786 /* get_service_params - get service-name dependent config information */
788 static void get_service_params(PIPE_PARAMS
*config
, char *service
)
790 const char *myname
= "get_service_params";
793 * Figure out the command time limit for this transport.
796 get_mail_conf_time2(service
, _MAXTIME
, var_command_maxtime
, 's', 1, 0);
799 * Give the poor tester a clue of what is going on.
802 msg_info("%s: time_limit %d", myname
, config
->time_limit
);
805 /* get_service_attr - get command-line attributes */
807 static void get_service_attr(PIPE_ATTR
*attr
, char **argv
)
809 const char *myname
= "get_service_attr";
812 char *user
; /* user name */
813 char *group
; /* group name */
814 char *size
; /* max message size */
825 attr
->chroot_dir
= 0;
826 attr
->eol
= vstring_strcpy(vstring_alloc(1), "\n");
827 attr
->null_sender
= vstring_strcpy(vstring_alloc(1), MAIL_ADDR_MAIL_DAEMON
);
828 attr
->size_limit
= 0;
831 * Iterate over the command-line attribute list.
833 for ( /* void */ ; *argv
!= 0; argv
++) {
838 if (strncasecmp("flags=", *argv
, sizeof("flags=") - 1) == 0) {
839 for (cp
= *argv
+ sizeof("flags=") - 1; *cp
; cp
++) {
842 attr
->flags
|= MAIL_COPY_BLANK
;
845 attr
->flags
|= MAIL_COPY_DELIVERED
;
848 attr
->flags
|= MAIL_COPY_FROM
;
851 attr
->flags
|= MAIL_COPY_ORIG_RCPT
;
854 attr
->flags
|= MAIL_COPY_RETURN_PATH
;
857 attr
->flags
|= PIPE_OPT_FINAL_DELIVERY
;
860 attr
->flags
|= MAIL_COPY_DOT
;
863 attr
->flags
|= MAIL_COPY_QUOTE
;
866 attr
->flags
|= PIPE_OPT_FOLD_HOST
;
869 attr
->flags
|= PIPE_OPT_QUOTE_LOCAL
;
872 attr
->flags
|= PIPE_OPT_FOLD_USER
;
875 msg_fatal("unknown flag: %c (ignored)", *cp
);
882 * user=username[:groupname]
884 else if (strncasecmp("user=", *argv
, sizeof("user=") - 1) == 0) {
885 user
= *argv
+ sizeof("user=") - 1;
886 if ((group
= split_at(user
, ':')) != 0) /* XXX clobbers argv */
889 if ((pwd
= getpwnam(user
)) == 0)
890 msg_fatal("%s: unknown username: %s", myname
, user
);
891 attr
->uid
= pwd
->pw_uid
;
893 if ((grp
= getgrnam(group
)) == 0)
894 msg_fatal("%s: unknown group: %s", myname
, group
);
895 attr
->gid
= grp
->gr_gid
;
897 attr
->gid
= pwd
->pw_gid
;
904 else if (strncasecmp("directory=", *argv
, sizeof("directory=") - 1) == 0) {
905 attr
->exec_dir
= mystrdup(*argv
+ sizeof("directory=") - 1);
911 else if (strncasecmp("chroot=", *argv
, sizeof("chroot=") - 1) == 0) {
912 attr
->chroot_dir
= mystrdup(*argv
+ sizeof("chroot=") - 1);
918 else if (strncasecmp("eol=", *argv
, sizeof("eol=") - 1) == 0) {
919 unescape(attr
->eol
, *argv
+ sizeof("eol=") - 1);
925 else if (strncasecmp("null_sender=", *argv
, sizeof("null_sender=") - 1) == 0) {
926 vstring_strcpy(attr
->null_sender
, *argv
+ sizeof("null_sender=") - 1);
930 * size=max_message_size (in bytes)
932 else if (strncasecmp("size=", *argv
, sizeof("size=") - 1) == 0) {
933 size
= *argv
+ sizeof("size=") - 1;
934 if ((attr
->size_limit
= off_cvt_string(size
)) < 0)
935 msg_fatal("%s: bad size= value: %s", myname
, size
);
941 else if (strncasecmp("argv=", *argv
, sizeof("argv=") - 1) == 0) {
942 *argv
+= sizeof("argv=") - 1; /* XXX clobbers argv */
943 attr
->command
= argv
;
951 msg_fatal("unknown attribute name: %s", *argv
);
955 * Sanity checks. Verify that every member has an acceptable value.
958 msg_fatal("missing user= command-line attribute");
959 if (attr
->command
== 0)
960 msg_fatal("missing argv= command-line attribute");
962 msg_fatal("user= command-line attribute specifies root privileges");
963 if (attr
->uid
== var_owner_uid
)
964 msg_fatal("user= command-line attribute specifies mail system owner %s",
967 msg_fatal("user= command-line attribute specifies privileged group id 0");
968 if (attr
->gid
== var_owner_gid
)
969 msg_fatal("user= command-line attribute specifies mail system owner %s group id %ld",
970 var_mail_owner
, (long) attr
->gid
);
971 if (attr
->gid
== var_sgid_gid
)
972 msg_fatal("user= command-line attribute specifies mail system %s group id %ld",
973 var_sgid_group
, (long) attr
->gid
);
976 * Give the poor tester a clue of what is going on.
979 msg_info("%s: uid %ld, gid %ld, flags %d, size %ld",
980 myname
, (long) attr
->uid
, (long) attr
->gid
,
981 attr
->flags
, (long) attr
->size_limit
);
984 /* eval_command_status - do something with command completion status */
986 static int eval_command_status(int command_status
, char *service
,
987 DELIVER_REQUEST
*request
, PIPE_ATTR
*attr
,
996 * Depending on the result, bounce or defer the message, and mark the
997 * recipient as done where appropriate.
999 switch (command_status
) {
1001 dsb_update(why
, "2.0.0", (attr
->flags
& PIPE_OPT_FINAL_DELIVERY
) ?
1002 "delivered" : "relayed", DSB_SKIP_RMTA
, DSB_SKIP_REPLY
,
1003 "delivered via %s service", service
);
1004 (void) DSN_FROM_DSN_BUF(why
);
1005 for (n
= 0; n
< request
->rcpt_list
.len
; n
++) {
1006 rcpt
= request
->rcpt_list
.info
+ n
;
1007 status
= sent(DEL_REQ_TRACE_FLAGS(request
->flags
),
1008 request
->queue_id
, &request
->msg_stats
, rcpt
,
1009 service
, &why
->dsn
);
1010 if (status
== 0 && (request
->flags
& DEL_REQ_FLAG_SUCCESS
))
1011 deliver_completed(request
->fp
, rcpt
->offset
);
1015 case PIPE_STAT_BOUNCE
:
1016 case PIPE_STAT_DEFER
:
1017 (void) DSN_FROM_DSN_BUF(why
);
1018 if (STR(why
->status
)[0] != '4') {
1019 for (n
= 0; n
< request
->rcpt_list
.len
; n
++) {
1020 rcpt
= request
->rcpt_list
.info
+ n
;
1021 status
= bounce_append(DEL_REQ_TRACE_FLAGS(request
->flags
),
1023 &request
->msg_stats
, rcpt
,
1024 service
, &why
->dsn
);
1026 deliver_completed(request
->fp
, rcpt
->offset
);
1030 for (n
= 0; n
< request
->rcpt_list
.len
; n
++) {
1031 rcpt
= request
->rcpt_list
.info
+ n
;
1032 result
|= defer_append(DEL_REQ_TRACE_FLAGS(request
->flags
),
1034 &request
->msg_stats
, rcpt
,
1035 service
, &why
->dsn
);
1039 case PIPE_STAT_CORRUPT
:
1040 /* XXX DSN should we send something? */
1041 result
|= DEL_STAT_DEFER
;
1044 msg_panic("eval_command_status: bad status %d", command_status
);
1051 /* deliver_message - deliver message with extreme prejudice */
1053 static int deliver_message(DELIVER_REQUEST
*request
, char *service
, char **argv
)
1055 const char *myname
= "deliver_message";
1056 static PIPE_PARAMS conf
;
1057 static PIPE_ATTR attr
;
1058 RECIPIENT_LIST
*rcpt_list
= &request
->rcpt_list
;
1059 DSN_BUF
*why
= dsb_create();
1061 ARGV
*expanded_argv
= 0;
1067 #define DELIVER_MSG_CLEANUP() { \
1069 if (expanded_argv) argv_free(expanded_argv); \
1073 msg_info("%s: from <%s>", myname
, request
->sender
);
1076 * Sanity checks. The get_service_params() and get_service_attr()
1077 * routines also do some sanity checks. Look up service attributes and
1078 * config information only once. This is safe since the information comes
1079 * from a trusted source, not from the delivery request.
1081 if (request
->nexthop
[0] == 0)
1082 msg_fatal("empty nexthop hostname");
1083 if (rcpt_list
->len
<= 0)
1084 msg_fatal("recipient count: %d", rcpt_list
->len
);
1085 if (attr
.command
== 0) {
1086 get_service_params(&conf
, service
);
1087 get_service_attr(&attr
, argv
);
1091 * The D flag cannot be specified for multi-recipient deliveries.
1093 if ((attr
.flags
& MAIL_COPY_DELIVERED
) && (rcpt_list
->len
> 1)) {
1094 dsb_simple(why
, "4.3.5", "mail system configuration error");
1095 deliver_status
= eval_command_status(PIPE_STAT_DEFER
, service
,
1096 request
, &attr
, why
);
1097 msg_warn("pipe flag `D' requires %s_destination_recipient_limit = 1",
1099 DELIVER_MSG_CLEANUP();
1100 return (deliver_status
);
1104 * The O flag cannot be specified for multi-recipient deliveries.
1106 if ((attr
.flags
& MAIL_COPY_ORIG_RCPT
) && (rcpt_list
->len
> 1)) {
1107 dsb_simple(why
, "4.3.5", "mail system configuration error");
1108 deliver_status
= eval_command_status(PIPE_STAT_DEFER
, service
,
1109 request
, &attr
, why
);
1110 msg_warn("pipe flag `O' requires %s_destination_recipient_limit = 1",
1112 DELIVER_MSG_CLEANUP();
1113 return (deliver_status
);
1117 * Check that this agent accepts messages this large.
1119 if (attr
.size_limit
!= 0 && request
->data_size
> attr
.size_limit
) {
1121 msg_info("%s: too big: size_limit = %ld, request->data_size = %ld",
1122 myname
, (long) attr
.size_limit
, request
->data_size
);
1123 dsb_simple(why
, "5.2.3", "message too large");
1124 deliver_status
= eval_command_status(PIPE_STAT_BOUNCE
, service
,
1125 request
, &attr
, why
);
1126 DELIVER_MSG_CLEANUP();
1127 return (deliver_status
);
1131 * Don't deliver a trace-only request.
1133 if (DEL_REQ_TRACE_ONLY(request
->flags
)) {
1139 dsb_simple(why
, "2.0.0", "delivers to command: %s", attr
.command
[0]);
1140 (void) DSN_FROM_DSN_BUF(why
);
1141 for (n
= 0; n
< request
->rcpt_list
.len
; n
++) {
1142 rcpt
= request
->rcpt_list
.info
+ n
;
1143 status
= sent(DEL_REQ_TRACE_FLAGS(request
->flags
),
1144 request
->queue_id
, &request
->msg_stats
,
1145 rcpt
, service
, &why
->dsn
);
1146 if (status
== 0 && (request
->flags
& DEL_REQ_FLAG_SUCCESS
))
1147 deliver_completed(request
->fp
, rcpt
->offset
);
1148 deliver_status
|= status
;
1150 DELIVER_MSG_CLEANUP();
1151 return (deliver_status
);
1155 * Report mail delivery loops. By definition, this requires
1156 * single-recipient delivery. Don't silently lose recipients.
1158 if (attr
.flags
& MAIL_COPY_DELIVERED
) {
1159 DELIVERED_HDR_INFO
*info
;
1163 if (request
->rcpt_list
.len
> 1)
1164 msg_panic("%s: delivered-to enabled with multi-recipient request",
1166 info
= delivered_hdr_init(request
->fp
, request
->data_offset
,
1168 rcpt
= request
->rcpt_list
.info
;
1169 loop_found
= delivered_hdr_find(info
, rcpt
->address
);
1170 delivered_hdr_free(info
);
1172 dsb_simple(why
, "5.4.6", "mail forwarding loop for %s",
1174 deliver_status
= eval_command_status(PIPE_STAT_BOUNCE
, service
,
1175 request
, &attr
, why
);
1176 DELIVER_MSG_CLEANUP();
1177 return (deliver_status
);
1182 * Deliver. Set the nexthop and sender variables, and expand the command
1183 * argument vector. Recipients will be expanded on the fly. XXX Rewrite
1184 * envelope and header addresses according to transport-specific
1187 if (vstream_fseek(request
->fp
, request
->data_offset
, SEEK_SET
) < 0)
1188 msg_fatal("seek queue file %s: %m", VSTREAM_PATH(request
->fp
));
1191 * A non-empty null sender replacement is subject to the 'q' flag.
1193 buf
= vstring_alloc(10);
1194 sender
= *request
->sender
? request
->sender
: STR(attr
.null_sender
);
1195 if (*sender
&& (attr
.flags
& PIPE_OPT_QUOTE_LOCAL
)) {
1196 quote_822_local(buf
, sender
);
1197 dict_update(PIPE_DICT_TABLE
, PIPE_DICT_SENDER
, STR(buf
));
1199 dict_update(PIPE_DICT_TABLE
, PIPE_DICT_SENDER
, sender
);
1200 if (attr
.flags
& PIPE_OPT_FOLD_HOST
) {
1201 vstring_strcpy(buf
, request
->nexthop
);
1202 lowercase(STR(buf
));
1203 dict_update(PIPE_DICT_TABLE
, PIPE_DICT_NEXTHOP
, STR(buf
));
1205 dict_update(PIPE_DICT_TABLE
, PIPE_DICT_NEXTHOP
, request
->nexthop
);
1206 vstring_sprintf(buf
, "%ld", (long) request
->data_size
);
1207 dict_update(PIPE_DICT_TABLE
, PIPE_DICT_SIZE
, STR(buf
));
1208 dict_update(PIPE_DICT_TABLE
, PIPE_DICT_CLIENT_ADDR
,
1209 request
->client_addr
);
1210 dict_update(PIPE_DICT_TABLE
, PIPE_DICT_CLIENT_HELO
,
1211 request
->client_helo
);
1212 dict_update(PIPE_DICT_TABLE
, PIPE_DICT_CLIENT_NAME
,
1213 request
->client_name
);
1214 dict_update(PIPE_DICT_TABLE
, PIPE_DICT_CLIENT_PORT
,
1215 request
->client_port
);
1216 dict_update(PIPE_DICT_TABLE
, PIPE_DICT_CLIENT_PROTO
,
1217 request
->client_proto
);
1218 dict_update(PIPE_DICT_TABLE
, PIPE_DICT_SASL_METHOD
,
1219 request
->sasl_method
);
1220 dict_update(PIPE_DICT_TABLE
, PIPE_DICT_SASL_USERNAME
,
1221 request
->sasl_username
);
1222 dict_update(PIPE_DICT_TABLE
, PIPE_DICT_SASL_SENDER
,
1223 request
->sasl_sender
);
1226 if ((expanded_argv
= expand_argv(service
, attr
.command
,
1227 rcpt_list
, attr
.flags
)) == 0) {
1228 dsb_simple(why
, "4.3.5", "mail system configuration error");
1229 deliver_status
= eval_command_status(PIPE_STAT_DEFER
, service
,
1230 request
, &attr
, why
);
1231 DELIVER_MSG_CLEANUP();
1232 return (deliver_status
);
1234 export_env
= argv_split(var_export_environ
, ", \t\r\n");
1236 command_status
= pipe_command(request
->fp
, why
,
1237 PIPE_CMD_UID
, attr
.uid
,
1238 PIPE_CMD_GID
, attr
.gid
,
1239 PIPE_CMD_SENDER
, sender
,
1240 PIPE_CMD_COPY_FLAGS
, attr
.flags
,
1241 PIPE_CMD_ARGV
, expanded_argv
->argv
,
1242 PIPE_CMD_TIME_LIMIT
, conf
.time_limit
,
1243 PIPE_CMD_EOL
, STR(attr
.eol
),
1244 PIPE_CMD_EXPORT
, export_env
->argv
,
1245 PIPE_CMD_CWD
, attr
.exec_dir
,
1246 PIPE_CMD_CHROOT
, attr
.chroot_dir
,
1247 PIPE_CMD_ORIG_RCPT
, rcpt_list
->info
[0].orig_addr
,
1248 PIPE_CMD_DELIVERED
, rcpt_list
->info
[0].address
,
1250 argv_free(export_env
);
1252 deliver_status
= eval_command_status(command_status
, service
, request
,
1258 DELIVER_MSG_CLEANUP();
1260 return (deliver_status
);
1263 /* pipe_service - perform service for client */
1265 static void pipe_service(VSTREAM
*client_stream
, char *service
, char **argv
)
1267 DELIVER_REQUEST
*request
;
1271 * This routine runs whenever a client connects to the UNIX-domain socket
1272 * dedicated to delivery via external command. What we see below is a
1273 * little protocol to (1) tell the queue manager that we are ready, (2)
1274 * read a request from the queue manager, and (3) report the completion
1275 * status of that request. All connection-management stuff is handled by
1276 * the common code in single_server.c.
1278 if ((request
= deliver_request_read(client_stream
)) != 0) {
1279 status
= deliver_message(request
, service
, argv
);
1280 deliver_request_done(client_stream
, request
, status
);
1284 /* pre_accept - see if tables have changed */
1286 static void pre_accept(char *unused_name
, char **unused_argv
)
1290 if ((table
= dict_changed_name()) != 0) {
1291 msg_info("table %s has changed -- restarting", table
);
1296 /* drop_privileges - drop privileges most of the time */
1298 static void drop_privileges(char *unused_name
, char **unused_argv
)
1300 set_eugid(var_owner_uid
, var_owner_gid
);
1303 /* pre_init - initialize */
1305 static void pre_init(char *unused_name
, char **unused_argv
)
1310 MAIL_VERSION_STAMP_DECLARE
;
1312 /* main - pass control to the single-threaded skeleton */
1314 int main(int argc
, char **argv
)
1316 static const CONFIG_TIME_TABLE time_table
[] = {
1317 VAR_COMMAND_MAXTIME
, DEF_COMMAND_MAXTIME
, &var_command_maxtime
, 1, 0,
1322 * Fingerprint executables and core dumps.
1324 MAIL_VERSION_STAMP_ALLOCATE
;
1326 single_server_main(argc
, argv
, pipe_service
,
1327 MAIL_SERVER_TIME_TABLE
, time_table
,
1328 MAIL_SERVER_PRE_INIT
, pre_init
,
1329 MAIL_SERVER_POST_INIT
, drop_privileges
,
1330 MAIL_SERVER_PRE_ACCEPT
, pre_accept
,
1331 MAIL_SERVER_PRIVILEGED
,