From: Wietse Venema Date: Fri, 8 Dec 2000 05:00:00 +0000 (-0500) Subject: snapshot-20001208 X-Git-Tag: v20010228~16 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=528b9b115cba4c6743a885afeb4edaf44132179e;p=thirdparty%2Fpostfix.git snapshot-20001208 --- diff --git a/postfix/.indent.pro b/postfix/.indent.pro index dd75ae0bd..693a39fb8 100644 --- a/postfix/.indent.pro +++ b/postfix/.indent.pro @@ -121,6 +121,7 @@ -TVBUF -TVSTREAM -TVSTREAM_POPEN_ARGS +-TVSTREAN_POPEN_ARGS -TVSTRING -TWAIT_STATUS_T -TWATCHDOG diff --git a/postfix/HISTORY b/postfix/HISTORY index 025415e5f..dd441493d 100644 --- a/postfix/HISTORY +++ b/postfix/HISTORY @@ -4544,3 +4544,35 @@ Apologies for any names omitted. Feature: specify "smtp_never_send_ehlo = no" to disable ESMTP. Someone asked for this long ago. Files: smtp/smtp.c, smtp/smtp_proto.c. + + Feature? Bugfix? The smtp client will now ignore server + replies that do not start with "CODE SPACE" or with "CODE + HYPHEN". Which means that "CODE TEXT" is now treated as + "CODE HYPHEN TEXT", instead of being treated as "CODE SPACE + TEXT", the way it was before. File: smtp/smtp_chat.c. + +20001203 + + Documentation: postmap(1) and postalias(1) did not document + the process exit status for "-q key". + +20001204 + + Bugfix: master no longer imported MAIL_CONF and other + necessary environmental parameters. Postfix now has + explicit "import_environment" and "export_environment" + configuration parameters that control what environment + parameters are imported from or exported to the external + environment. Files: util/clean_env.c, util/spawn_command.c, + util/vstream_popen.c, global/pipe_command.c, and everything + that uses this code. + +20001208 + + Bugfix: while processing massive amounts of one-recipient + mail, qmgr could deadlock for 10 seconds while sending a + bounce message. All queue manager bounce send requests are + now implemented asynchronously. Files: global/abounce.[hc] + (asynchronous bounce client), qmgr/qmgr_active.c. Problem + reported by El Bunzo (webpower.nl) and Tiger Technologies + (tigertech.com). diff --git a/postfix/RELEASE_NOTES b/postfix/RELEASE_NOTES index 582a8ceaa..4b481b439 100644 --- a/postfix/RELEASE_NOTES +++ b/postfix/RELEASE_NOTES @@ -2,20 +2,27 @@ Incompatible changes with snapshot-2000XXXX =========================================== The "sun_mailtool_compatibility" is going away (a compatibility mode -that turns of kernel locks on mailbox files). It still works, but +that turns off kernel locks on mailbox files). It still works, but a warning is logged. Instead, specify the mailbox locking strategy via the new "mailbox_delivery_lock" parameter. Major changes with snapshot-2000XXXX ==================================== -The locking style for delivery to mailbox is now fully configurable -at runtime. The new configuration parameter is "mailbox_delivery_lock". +The mailbox locking style is now fully configurable at runtime. +The new configuration parameter is "mailbox_delivery_lock". Depending on the operating system type, mailboxes can be locked -with one or more of "flock", "fcntl" or "dotlock". The default -setting of "mailbox_delivery_lock" is therefore system dependent. +with one or more of "flock", "fcntl" or "dotlock". This also applies +to "/file/name" deliveries by the Postfix local delivery agent. +The default setting of "mailbox_delivery_lock" is system dependent. The command "postconf -l" shows the available locking styles. +The "import_environment" and "export_environment" configuration +parameters now control what environment variables Postfix will +import from its parent and what it variables Postfix will pass on +to a non-Postfix process. It is not safe to import or export +everything, and different sites may have different needs. + Incompatible changes with snapshot-20001121 =========================================== diff --git a/postfix/conf/sample-misc.cf b/postfix/conf/sample-misc.cf index 9efed230e..0741e0e20 100644 --- a/postfix/conf/sample-misc.cf +++ b/postfix/conf/sample-misc.cf @@ -38,6 +38,15 @@ default_transport = smtp # double_bounce_sender = double-bounce +# The export_environment parameter specifies the names of environment +# parameters that Postfix will export to non-Postfix processes. +# +# - TZ is needed for sane time keeping on most SYSV-ish systems +# +# Specify a list of names separated by whitespace or comma. +# +export_environment = TZ + # The hash_queue_depth parameter specifies the number of subdirectory # levels below the queue directories listed in the hash_queue_names # parameter. @@ -70,6 +79,20 @@ hash_queue_names = defer # hopcount_limit = 50 +# The import_environment parameter specifies the names of environment +# parameters that Postfix processes will import from their parent +# environment. +# +# - TZ is needed for sane time keeping on most SYSV-ish systems +# - DISPLAY and XAUTHORITY are needed for debugging Postfix daemons +# with an X-windows debugger. +# - MAIL_CONFIG is needed to make "postfix -c" work. +# +# Specify a list of names separated by whitespace or comma. +# +# import_environment = MAIL_CONFIG TZ XAUTHORITY DISPLAY HOME PURIFYOPTIONS +import_environment = MAIL_CONFIG TZ XAUTHORITY DISPLAY + # The inet_interfaces parameter specifies the network interface # addresses that this mail system receives mail on. By default, # the software claims all active interfaces on the machine. The diff --git a/postfix/html/local.8.html b/postfix/html/local.8.html index fabb9c4ba..d9a39e785 100644 --- a/postfix/html/local.8.html +++ b/postfix/html/local.8.html @@ -318,9 +318,9 @@ LOCAL(8) LOCAL(8) the right-hand side of the owner alias, instead using of the left-hand side address. - forward_path - Search list for .forward files. The names are sub- - ject to $name expansion. + export_environment + List of names of environment parameters that can be + exported to non-Postfix processes. @@ -335,11 +335,15 @@ LOCAL(8) LOCAL(8) LOCAL(8) LOCAL(8) + forward_path + Search list for .forward files. The names are sub- + ject to $name expansion. + local_command_shell - Shell to use for external command execution (for - example, /some/where/smrsh -c). When a shell is + Shell to use for external command execution (for + example, /some/where/smrsh -c). When a shell is specified, it is invoked even when the command con- - tains no shell built-in commands or meta charac- + tains no shell built-in commands or meta charac- ters. owner_request_special @@ -347,10 +351,10 @@ LOCAL(8) LOCAL(8) addresses. prepend_delivered_header - Prepend an optional Delivered-To: header upon - external forwarding, delivery to command or file. - Specify zero or more of: command, file, forward. - Turning off Delivered-To: when forwarding mail is + Prepend an optional Delivered-To: header upon + external forwarding, delivery to command or file. + Specify zero or more of: command, file, forward. + Turning off Delivered-To: when forwarding mail is not recommended. recipient_delimiter @@ -358,38 +362,34 @@ LOCAL(8) LOCAL(8) test_home_directory Require that a recipient's home directory is acces- - sible by the recipient before attempting delivery. + sible by the recipient before attempting delivery. Mailbox delivery fallback_transport Message transport for recipients that are not found - in the UNIX passwd database. This parameter over- + in the UNIX passwd database. This parameter over- rides luser_relay. home_mailbox - Pathname of a mailbox relative to a user's home + Pathname of a mailbox relative to a user's home directory. Specify a path ending in / for maildir- style delivery. luser_relay - Destination (@domain or address) for non-existent - users. The address is subjected to $name expan- + Destination (@domain or address) for non-existent + users. The address is subjected to $name expan- sion. mail_spool_directory - Directory with UNIX-style mailboxes. The default + Directory with UNIX-style mailboxes. The default pathname is system dependent. mailbox_command - External command to use for mailbox delivery. The + External command to use for mailbox delivery. The command executes with the recipient privileges - (exception: root). The string is subject to $name + (exception: root). The string is subject to $name expansions. - mailbox_transport - Message transport to use for mailbox delivery to - all local recipients, whether or not they are found - 6 @@ -401,59 +401,59 @@ LOCAL(8) LOCAL(8) LOCAL(8) LOCAL(8) - in the UNIX passwd database. This parameter over- - rides all other configuration parameters that con- + mailbox_transport + Message transport to use for mailbox delivery to + all local recipients, whether or not they are found + in the UNIX passwd database. This parameter over- + rides all other configuration parameters that con- trol mailbox delivery, including luser_relay. Locking controls deliver_lock_attempts - Limit the number of attempts to acquire an exclu- + Limit the number of attempts to acquire an exclu- sive lock on a mailbox or external file. deliver_lock_delay - Time in seconds between successive attempts to + Time in seconds between successive attempts to acquire an exclusive lock. stale_lock_time Limit the time after which a stale lock is removed. mailbox__delivery_lock - What file locking method(s) to use when delivering - to a UNIX-style mailbox. The default setting is - system dependent. For a list of available file + What file locking method(s) to use when delivering + to a UNIX-style mailbox. The default setting is + system dependent. For a list of available file locking methods, use the postconf -l command. Resource controls command_time_limit - Limit the amount of time for delivery to external + Limit the amount of time for delivery to external command. duplicate_filter_limit - Limit the size of the duplicate filter for results + Limit the size of the duplicate filter for results from alias etc. expansion. line_length_limit - Limit the amount of memory used for processing a + Limit the amount of memory used for processing a partial input line. local_destination_concurrency_limit Limit the number of parallel deliveries to the same - user. The default limit is taken from the + user. The default limit is taken from the default_destination_concurrency_limit parameter. local_destination_recipient_limit - Limit the number of recipients per message deliv- - ery. The default limit is taken from the + Limit the number of recipients per message deliv- + ery. The default limit is taken from the default_destination_recipient_limit parameter. Security controls allow_mail_to_commands - Restrict the usage of mail delivery to external + Restrict the usage of mail delivery to external command. - allow_mail_to_files - Restrict the usage of mail delivery to external - file. @@ -467,25 +467,29 @@ LOCAL(8) LOCAL(8) LOCAL(8) LOCAL(8) + allow_mail_to_files + Restrict the usage of mail delivery to external + file. + command_expansion_filter - What characters are allowed to appear in $name - expansions of mailbox_command. Illegal characters + What characters are allowed to appear in $name + expansions of mailbox_command. Illegal characters are replaced by underscores. default_privs - Default rights for delivery to external file or + Default rights for delivery to external file or command. forward_expansion_filter - What characters are allowed to appear in $name - expansions of forward_path. Illegal characters are + What characters are allowed to appear in $name + expansions of forward_path. Illegal characters are replaced by underscores. HISTORY - The Delivered-To: header appears in the qmail system by + The Delivered-To: header appears in the qmail system by Daniel Bernstein. - The maildir structure appears in the qmail system by + The maildir structure appears in the qmail system by Daniel Bernstein. SEE ALSO @@ -496,7 +500,7 @@ LOCAL(8) LOCAL(8) qmgr(8) queue manager LICENSE - The Secure Mailer license must be distributed with this + The Secure Mailer license must be distributed with this software. AUTHOR(S) @@ -520,10 +524,6 @@ LOCAL(8) LOCAL(8) - - - - 8 diff --git a/postfix/html/master.8.html b/postfix/html/master.8.html index 9edfc94ae..b1784ea00 100644 --- a/postfix/html/master.8.html +++ b/postfix/html/master.8.html @@ -102,6 +102,13 @@ MASTER(8) MASTER(8) command after a configuration change. Miscellaneous + import_environment + + export_environment + Lists of names of environment parameters that can + be imported from (exported to) non-Postfix pro- + cesses. + mail_owner The owner of the mail queue and of most Postfix processes. @@ -117,14 +124,7 @@ MASTER(8) MASTER(8) also the root directory of Postfix daemons that run chrooted. -Resource controls - default_process_limit - Default limit for the number of simultaneous child - processes that provide a given service. - max_idle - Limit the time in seconds that a child process - waits between service requests. @@ -137,6 +137,15 @@ MASTER(8) MASTER(8) MASTER(8) MASTER(8) +Resource controls + default_process_limit + Default limit for the number of simultaneous child + processes that provide a given service. + + max_idle + Limit the time in seconds that a child process + waits between service requests. + max_use Limit the number of service requests handled by a child process. @@ -175,15 +184,6 @@ MASTER(8) MASTER(8) - - - - - - - - - diff --git a/postfix/html/pipe.8.html b/postfix/html/pipe.8.html index c98431c7d..207286715 100644 --- a/postfix/html/pipe.8.html +++ b/postfix/html/pipe.8.html @@ -177,20 +177,20 @@ PIPE(8) PIPE(8) command after a configuration change. Miscellaneous + export_environment + List of names of environment parameters that can be + exported to non-Postfix processes. + mail_owner - The process privileges used while not running an + The process privileges used while not running an external command. Resource controls - In the text below, transport is the first field in a mas- + In the text below, transport is the first field in a mas- ter.cf entry. transport_destination_concurrency_limit Limit the number of parallel deliveries to the same - destination, for delivery via the named transport. - The default limit is taken from the default_desti- - nation_concurrency_limit parameter. The limit is - enforced by the Postfix queue manager. @@ -203,18 +203,23 @@ PIPE(8) PIPE(8) PIPE(8) PIPE(8) + destination, for delivery via the named transport. + The default limit is taken from the default_desti- + nation_concurrency_limit parameter. The limit is + enforced by the Postfix queue manager. + transport_destination_recipient_limit - Limit the number of recipients per message deliv- - ery, for delivery via the named transport. The - default limit is taken from the default_destina- - tion_recipient_limit parameter. The limit is + Limit the number of recipients per message deliv- + ery, for delivery via the named transport. The + default limit is taken from the default_destina- + tion_recipient_limit parameter. The limit is enforced by the Postfix queue manager. transport_time_limit - Limit the time for delivery to external command, - for delivery via the named transport. The default - limit is taken from the command_time_limit parame- - ter. The limit is enforced by the Postfix queue + Limit the time for delivery to external command, + for delivery via the named transport. The default + limit is taken from the command_time_limit parame- + ter. The limit is enforced by the Postfix queue manager. SEE ALSO @@ -224,7 +229,7 @@ PIPE(8) PIPE(8) syslogd(8) system logging LICENSE - The Secure Mailer license must be distributed with this + The Secure Mailer license must be distributed with this software. AUTHOR(S) @@ -249,11 +254,6 @@ PIPE(8) PIPE(8) - - - - - diff --git a/postfix/html/postalias.1.html b/postfix/html/postalias.1.html index e8540371f..4d6e097bb 100644 --- a/postfix/html/postalias.1.html +++ b/postfix/html/postalias.1.html @@ -109,6 +109,10 @@ POSTALIAS(1) POSTALIAS(1) put means no problems were detected. Duplicate entries are skipped and are flagged with a warning. + postalias terminates with zero exit status in case of suc- + cess (including successful postmap -q lookup) and termi- + nates with non-zero exit status in case of failure. + BUGS The "delete key" support is limited to one delete opera- tion per command invocation. @@ -120,10 +124,6 @@ POSTALIAS(1) POSTALIAS(1) MAIL_VERBOSE Enable verbose logging for debugging purposes. -CONFIGURATION PARAMETERS - The following main.cf parameters are especially relevant - to this program. See the Postfix main.cf file for syntax - details and for default values. @@ -137,6 +137,11 @@ POSTALIAS(1) POSTALIAS(1) POSTALIAS(1) POSTALIAS(1) +CONFIGURATION PARAMETERS + The following main.cf parameters are especially relevant + to this program. See the Postfix main.cf file for syntax + details and for default values. + database_type Default alias database type. On many UNIX systems, the default type is either dbm or hash. @@ -183,11 +188,6 @@ POSTALIAS(1) POSTALIAS(1) - - - - - diff --git a/postfix/html/postdrop.1.html b/postfix/html/postdrop.1.html index a994ce37b..b9f3b7963 100644 --- a/postfix/html/postdrop.1.html +++ b/postfix/html/postdrop.1.html @@ -53,12 +53,12 @@ POSTDROP(1) POSTDROP(1) default values. Use the postfix reload command after a configuration change. - queue_directory - Top-level directory of the Postfix queue. This is - also the root directory of Postfix daemons that run - chrooted. - + import_environment + List of names of environment parameters that can be + imported from non-Postfix processes. + queue_directory + Top-level directory of the Postfix queue. This is @@ -71,12 +71,15 @@ POSTDROP(1) POSTDROP(1) POSTDROP(1) POSTDROP(1) + also the root directory of Postfix daemons that run + chrooted. + SEE ALSO sendmail(1) compatibility interface syslogd(8) system logging LICENSE - The Secure Mailer license must be distributed with this + The Secure Mailer license must be distributed with this software. AUTHOR(S) @@ -121,9 +124,6 @@ POSTDROP(1) POSTDROP(1) - - - diff --git a/postfix/html/postmap.1.html b/postfix/html/postmap.1.html index b81278cbc..77833681c 100644 --- a/postfix/html/postmap.1.html +++ b/postfix/html/postmap.1.html @@ -139,6 +139,10 @@ POSTMAP(1) POSTMAP(1) skipped and are flagged with a warning. + postmap terminates with zero exit status in case of suc- + cess (including successful postmap -q lookup) and termi- + nates with non-zero exit status in case of failure. + BUGS The "delete key" support is limited to one delete opera- tion per command invocation. @@ -185,10 +189,6 @@ POSTMAP(1) POSTMAP(1) - - - - diff --git a/postfix/html/smtp.8.html b/postfix/html/smtp.8.html index dc1ea633d..99b5aa3ae 100644 --- a/postfix/html/smtp.8.html +++ b/postfix/html/smtp.8.html @@ -109,8 +109,8 @@ SMTP(8) SMTP(8) ignore_mx_lookup_error When a name server fails to respond to an MX query, - search for an A record instead of assuming that the - name server will recover. + search for an A record instead deferring mail + delivery. inet_interfaces The network interface addresses that this mail sys- @@ -140,6 +140,9 @@ SMTP(8) SMTP(8) smtp_always_send_ehlo Always send EHLO at the start of a connection. + smtp_never_send_ehlo + Never send EHLO at the start of a connection. + smtp_skip_4xx_greeting Skip servers that greet us with a 4xx status code. @@ -189,9 +192,6 @@ SMTP(8) SMTP(8) destination. The default limit is taken from the default_destination_concurrency_limit parameter. - smtp_destination_recipient_limit - Limit the number of recipients per message - 3 @@ -203,7 +203,9 @@ SMTP(8) SMTP(8) SMTP(8) SMTP(8) - delivery. The default limit is taken from the + smtp_destination_recipient_limit + Limit the number of recipients per message deliv- + ery. The default limit is taken from the default_destination_recipient_limit parameter. Timeout controls @@ -258,8 +260,6 @@ SMTP(8) SMTP(8) - - 4 diff --git a/postfix/html/spawn.8.html b/postfix/html/spawn.8.html index af8466922..b844abf3a 100644 --- a/postfix/html/spawn.8.html +++ b/postfix/html/spawn.8.html @@ -83,16 +83,20 @@ SPAWN(8) SPAWN(8) command after a configuration change. Miscellaneous + export_environment + List of names of environment parameters that can be + exported to non-Postfix processes. + mail_owner - The process privileges used while not running an + The process privileges used while not running an external command. Resource control service_command_time_limit - The amount of time the command is allowed to run + The amount of time the command is allowed to run before it is killed with force. The service name is - the name of the entry in the master.cf file. The - default time limit is given by the global com- + the name of the entry in the master.cf file. The + default time limit is given by the global com- mand_time_limit configuration parameter. SEE ALSO @@ -100,7 +104,7 @@ SPAWN(8) SPAWN(8) syslogd(8) system logging LICENSE - The Secure Mailer license must be distributed with this + The Secure Mailer license must be distributed with this software. AUTHOR(S) @@ -124,10 +128,6 @@ SPAWN(8) SPAWN(8) - - - - 2 diff --git a/postfix/man/man1/postalias.1 b/postfix/man/man1/postalias.1 index 88bc2242c..5637bbef4 100644 --- a/postfix/man/man1/postalias.1 +++ b/postfix/man/man1/postalias.1 @@ -85,6 +85,10 @@ The name of the alias database source file when rebuilding a database. Problems are logged to the standard error stream. No output means no problems were detected. Duplicate entries are skipped and are flagged with a warning. + +\fBpostalias\fR terminates with zero exit status in case of success +(including successful \fBpostmap -q\fR lookup) and terminates +with non-zero exit status in case of failure. .SH BUGS .ad .fi diff --git a/postfix/man/man1/postdrop.1 b/postfix/man/man1/postdrop.1 index 42a67bbf9..eb293df76 100644 --- a/postfix/man/man1/postdrop.1 +++ b/postfix/man/man1/postdrop.1 @@ -60,6 +60,9 @@ library can't be trusted. See the Postfix \fBmain.cf\fR file for syntax details and for default values. Use the \fBpostfix reload\fR command after a configuration change. +.IP \fBimport_environment\fR +List of names of environment parameters that can be imported +from non-Postfix processes. .IP \fBqueue_directory\fR Top-level directory of the Postfix queue. This is also the root directory of Postfix daemons that run chrooted. diff --git a/postfix/man/man1/postmap.1 b/postfix/man/man1/postmap.1 index 384d624fb..bdcd3bf16 100644 --- a/postfix/man/man1/postmap.1 +++ b/postfix/man/man1/postmap.1 @@ -102,6 +102,10 @@ The name of the lookup table source file when rebuilding a database. Problems and transactions are logged to the standard error stream. No output means no problems. Duplicate entries are skipped and are flagged with a warning. + +\fBpostmap\fR terminates with zero exit status in case of success +(including successful \fBpostmap -q\fR lookup) and terminates +with non-zero exit status in case of failure. .SH BUGS .ad .fi diff --git a/postfix/man/man8/local.8 b/postfix/man/man8/local.8 index d7a9450dc..b0795386d 100644 --- a/postfix/man/man8/local.8 +++ b/postfix/man/man8/local.8 @@ -291,6 +291,9 @@ Enable or disable notification of new mail via the When delivering to an alias that has an owner- companion alias, set the envelope sender address to the right-hand side of the owner alias, instead using of the left-hand side address. +.IP \fBexport_environment\fR +List of names of environment parameters that can be exported +to non-Postfix processes. .IP \fBforward_path\fR Search list for .forward files. The names are subject to \fI$name\fR expansion. diff --git a/postfix/man/man8/master.8 b/postfix/man/man8/master.8 index 855d3ee20..ad4f03444 100644 --- a/postfix/man/man8/master.8 +++ b/postfix/man/man8/master.8 @@ -93,6 +93,10 @@ a configuration change. .SH Miscellaneous .ad .fi +.IP \fBimport_environment\fR +.IP \fBexport_environment\fR +Lists of names of environment parameters that can be imported +from (exported to) non-Postfix processes. .IP \fBmail_owner\fR The owner of the mail queue and of most Postfix processes. .IP \fBcommand_directory\fR diff --git a/postfix/man/man8/pipe.8 b/postfix/man/man8/pipe.8 index 13a569674..7fb5787ba 100644 --- a/postfix/man/man8/pipe.8 +++ b/postfix/man/man8/pipe.8 @@ -141,6 +141,9 @@ a configuration change. .SH Miscellaneous .ad .fi +.IP \fBexport_environment\fR +List of names of environment parameters that can be exported +to non-Postfix processes. .IP \fBmail_owner\fR The process privileges used while not running an external command. .SH "Resource controls" diff --git a/postfix/man/man8/smtp.8 b/postfix/man/man8/smtp.8 index 35553290a..976874a97 100644 --- a/postfix/man/man8/smtp.8 +++ b/postfix/man/man8/smtp.8 @@ -97,7 +97,7 @@ Hosts to hand off mail to if a message destination is not found or if a destination is unreachable. .IP \fBignore_mx_lookup_error\fR When a name server fails to respond to an MX query, search for an -A record instead of assuming that the name server will recover. +A record instead deferring mail delivery. .IP \fBinet_interfaces\fR The network interface addresses that this mail system receives mail on. When any of those addresses appears in the list of mail @@ -108,6 +108,8 @@ When this parameter includes the \fBprotocol\fR class, send mail to the postmaster with transcripts of SMTP sessions with protocol errors. .IP \fBsmtp_always_send_ehlo\fR Always send EHLO at the start of a connection. +.IP \fBsmtp_never_send_ehlo\fR +Never send EHLO at the start of a connection. .IP \fBsmtp_skip_4xx_greeting\fR Skip servers that greet us with a 4xx status code. .IP \fBsmtp_skip_5xx_greeting\fR diff --git a/postfix/man/man8/spawn.8 b/postfix/man/man8/spawn.8 index 7ea3463cd..05878a6c2 100644 --- a/postfix/man/man8/spawn.8 +++ b/postfix/man/man8/spawn.8 @@ -76,6 +76,9 @@ a configuration change. .SH Miscellaneous .ad .fi +.IP \fBexport_environment\fR +List of names of environment parameters that can be exported +to non-Postfix processes. .IP \fBmail_owner\fR The process privileges used while not running an external command. .SH Resource control diff --git a/postfix/src/global/Makefile.in b/postfix/src/global/Makefile.in index cd6e5ed3d..c19cd75ae 100644 --- a/postfix/src/global/Makefile.in +++ b/postfix/src/global/Makefile.in @@ -18,7 +18,7 @@ SRCS = been_here.c bounce.c canon_addr.c cleanup_strerror.c clnt_stream.c \ sent.c smtp_stream.c split_addr.c string_list.c sys_exits.c \ timed_ipc.c tok822_find.c tok822_node.c tok822_parse.c \ tok822_resolve.c tok822_rewrite.c tok822_tree.c xtext.c bounce_log.c \ - flush_clnt.c mail_conf_time.c mbox_conf.c mbox_open.c + flush_clnt.c mail_conf_time.c mbox_conf.c mbox_open.c abounce.c OBJS = been_here.o bounce.o canon_addr.o cleanup_strerror.o clnt_stream.o \ debug_peer.o debug_process.o defer.o deliver_completed.o \ deliver_flock.o deliver_pass.o deliver_request.o domain_list.o \ @@ -38,7 +38,7 @@ OBJS = been_here.o bounce.o canon_addr.o cleanup_strerror.o clnt_stream.o \ sent.o smtp_stream.o split_addr.o string_list.o sys_exits.o \ timed_ipc.o tok822_find.o tok822_node.o tok822_parse.o \ tok822_resolve.o tok822_rewrite.o tok822_tree.o xtext.o bounce_log.o \ - flush_clnt.o mail_conf_time.o mbox_conf.o mbox_open.o + flush_clnt.o mail_conf_time.o mbox_conf.o mbox_open.o abounce.o HDRS = been_here.h bounce.h canon_addr.h cleanup_user.h clnt_stream.h \ config.h debug_peer.h debug_process.h defer.h deliver_completed.h \ deliver_flock.h deliver_pass.h deliver_request.h domain_list.h \ @@ -54,7 +54,7 @@ HDRS = been_here.h bounce.h canon_addr.h cleanup_user.h clnt_stream.h \ recipient_list.h record.h resolve_clnt.h resolve_local.h \ rewrite_clnt.h sent.h smtp_stream.h split_addr.h string_list.h \ sys_exits.h timed_ipc.h tok822.h xtext.h bounce_log.h flush_clnt.h \ - mbox_conf.h mbox_open.h + mbox_conf.h mbox_open.h abounce.h TESTSRC = rec2stream.c stream2rec.c recdump.c WARN = -W -Wformat -Wimplicit -Wmissing-prototypes \ -Wparentheses -Wstrict-prototypes -Wswitch -Wuninitialized \ @@ -716,6 +716,8 @@ mbox_open.o: ../../include/vstream.h mbox_open.o: ../../include/vbuf.h mbox_open.o: ../../include/vstring.h mbox_open.o: ../../include/safe_open.h +mbox_open.o: ../../include/iostuff.h +mbox_open.o: ../../include/mymalloc.h mbox_open.o: dot_lockfile.h mbox_open.o: deliver_flock.h mbox_open.o: ../../include/myflock.h diff --git a/postfix/src/global/abounce.c b/postfix/src/global/abounce.c new file mode 100644 index 000000000..bfda481d5 --- /dev/null +++ b/postfix/src/global/abounce.c @@ -0,0 +1,208 @@ +/*++ +/* NAME +/* abounce 3 +/* SUMMARY +/* asynchronous bounce/defer service client +/* SYNOPSIS +/* #include +/* +/* void abounce_flush(flags, queue, id, sender, callback, context) +/* int flags; +/* const char *queue; +/* const char *id; +/* const char *sender; +/* void (*callback)(int status, char *context); +/* char *context; +/* +/* void adefer_flush(flags, queue, id, sender, callback, context) +/* int flags; +/* const char *queue; +/* const char *id; +/* const char *sender; +/* void (*callback)(int status, char *context); +/* char *context; +/* +/* void adefer_warn(flags, queue, id, sender, callback, context) +/* int flags; +/* const char *queue; +/* const char *id; +/* const char *sender; +/* void (*callback)(int status, char *context); +/* char *context; +/* DESCRIPTION +/* This module implements an asynchronous interface to the +/* bounce/defer service for submitting sender notifications +/* without waiting for completion of the request. +/* +/* abounce_flush() bounces the specified message to +/* the specified sender, including the bounce log that was +/* built with bounce_append(). +/* +/* adefer_flush() bounces the specified message to +/* the specified sender, including the defer log that was +/* built with defer_append(). +/* +/* adefer_warn() sends a "mail is delayed" notification to +/* the specified sender, including the defer log that was +/* built with defer_append(). +/* +/* Arguments: +/* .IP flags +/* The bitwise OR of zero or more of the following (specify +/* BOUNCE_FLAG_NONE to request no special processing): +/* .RS +/* .IP BOUNCE_FLAG_CLEAN +/* Delete the bounce log in case of an error (as in: pretend +/* that we never even tried to bounce this message). +/* .IP BOUNCE_FLAG_COPY +/* Request that a postmaster copy is sent. +/* .RE +/* .IP queue +/* The message queue name of the original message file. +/* .IP id +/* The message queue id if the original message file. The bounce log +/* file has the same name as the original message file. +/* .IP sender +/* The sender envelope address. +/* .IP callback +/* Name of a routine that receives the notification status as +/* documented for bounce_flush() or defer_flush(). +/* .IP context +/* Application-specific context that is passed through to the +/* callback routine. Use proper casts or the world will come +/* to an end. +/* DIAGNOSTICS +/* In case of success, these functions log the action, and return a +/* zero result via the callback routine. Otherwise, the functions +/* return a non-zero result via the callback routine, and when +/* BOUNCE_FLAG_CLEAN is disabled, log that message delivery is deferred. +/* LICENSE +/* .ad +/* .fi +/* The Secure Mailer license must be distributed with this software. +/* AUTHOR(S) +/* Wietse Venema +/* IBM T.J. Watson Research +/* P.O. Box 704 +/* Yorktown Heights, NY 10598, USA +/*--*/ + +/* System library. */ + +#include + +/* Utility library. */ + +#include +#include +#include +#include + +/* Global library. */ + +#include +#include + +/* Application-specific. */ + + /* + * Each bounce/defer flush/warn request is implemented by sending the + * request to the bounce/defer server, and by creating a pseudo thread that + * suspends itself until the server replies (or dies). Upon wakeup, the + * pseudo thread delivers the request completion status to the application + * and destroys itself. The structure below maintains all the necessary + * request state while the pseudo thread is suspended. + */ +typedef struct { + int command; /* bounce request type */ + int flags; /* bounce options */ + char *id; /* queue ID for logging */ + ABOUNCE_FN callback; /* application callback */ + char *context; /* application context */ + VSTREAM *fp; /* server I/O handle */ +} ABOUNCE; + +/* abounce_done - deliver status to application and clean up pseudo thread */ + +static void abounce_done(ABOUNCE *ap, int status) +{ + (void) vstream_fclose(ap->fp); + if (status != 0 && (ap->flags & BOUNCE_FLAG_CLEAN) == 0) + msg_info("%s: status=deferred (%s failed)", ap->id, + ap->command == BOUNCE_CMD_FLUSH ? "bounce" : + ap->command == BOUNCE_CMD_WARN ? "delay warning" : + "whatever"); + ap->callback(status, ap->context); + myfree(ap->id); + myfree((char *) ap); +} + +/* abounce_event - resume pseudo thread after server reply event */ + +static void abounce_event(int unused_event, char *context) +{ + ABOUNCE *ap = (ABOUNCE *) context; + int status; + + event_disable_readwrite(vstream_fileno(ap->fp)); + abounce_done(ap, mail_scan(ap->fp, "%d", &status) == 1 ? status : -1); +} + +/* abounce_request - suspend pseudo thread until server reply event */ + +static void abounce_request(const char *class, const char *service, + int command, int flags, + const char *queue, const char *id, + const char *sender, + ABOUNCE_FN callback, + char *context) +{ + ABOUNCE *ap; + + /* + * Save pseudo thread state. Connect to the server. Send the request and + * suspend the pseudo thread until the server replies (or dies). + */ + ap = (ABOUNCE *) mymalloc(sizeof(*ap)); + ap->command = command; + ap->flags = flags; + ap->id = mystrdup(id); + ap->callback = callback; + ap->context = context; + ap->fp = mail_connect_wait(class, service); + + if (mail_print(ap->fp, "%d %d %s %s %s %s", command, + flags, queue, id, sender, MAIL_EOF) == 0 + && vstream_fflush(ap->fp) == 0) { + event_enable_read(vstream_fileno(ap->fp), abounce_event, (char *) ap); + } else { + abounce_done(ap, -1); + } +} + +/* abounce_flush - asynchronous bounce flush */ + +void abounce_flush(int flags, const char *queue, const char *id, + const char *sender, ABOUNCE_FN callback, char *context) +{ + abounce_request(MAIL_CLASS_PRIVATE, MAIL_SERVICE_BOUNCE, BOUNCE_CMD_FLUSH, + flags, queue, id, sender, callback, context); +} + +/* adefer_flush - asynchronous defer flush */ + +void adefer_flush(int flags, const char *queue, const char *id, + const char *sender, ABOUNCE_FN callback, char *context) +{ + abounce_request(MAIL_CLASS_PRIVATE, MAIL_SERVICE_DEFER, BOUNCE_CMD_FLUSH, + flags, queue, id, sender, callback, context); +} + +/* adefer_warn - send copy of defer log to sender as warning bounce */ + +void adefer_warn(int flags, const char *queue, const char *id, + const char *sender, ABOUNCE_FN callback, char *context) +{ + abounce_request(MAIL_CLASS_PRIVATE, MAIL_SERVICE_DEFER, BOUNCE_CMD_WARN, + flags, queue, id, sender, callback, context); +} diff --git a/postfix/src/global/abounce.h b/postfix/src/global/abounce.h new file mode 100644 index 000000000..893224875 --- /dev/null +++ b/postfix/src/global/abounce.h @@ -0,0 +1,39 @@ +#ifndef _ABOUNCE_H_INCLUDED_ +#define _ABOUNCE_H_INCLUDED_ + +/*++ +/* NAME +/* abounce 3h +/* SUMMARY +/* asynchronous bounce/defer service client +/* SYNOPSIS +/* #include +/* DESCRIPTION +/* .nf + + /* + * Global library. + */ +#include + + /* + * Client interface. + */ +typedef void (*ABOUNCE_FN) (int, char *); + +extern void abounce_flush(int, const char *, const char *, const char *, ABOUNCE_FN, char *); +extern void adefer_flush(int, const char *, const char *, const char *, ABOUNCE_FN, char *); +extern void adefer_warn(int, const char *, const char *, const char *, ABOUNCE_FN, char *); + +/* LICENSE +/* .ad +/* .fi +/* The Secure Mailer license must be distributed with this software. +/* AUTHOR(S) +/* Wietse Venema +/* IBM T.J. Watson Research +/* P.O. Box 704 +/* Yorktown Heights, NY 10598, USA +/*--*/ + +#endif diff --git a/postfix/src/global/mail_params.c b/postfix/src/global/mail_params.c index df1ca9363..14a588c8f 100644 --- a/postfix/src/global/mail_params.c +++ b/postfix/src/global/mail_params.c @@ -60,6 +60,9 @@ /* char *var_relay_domains; /* char *var_fflush_domains; /* +/* char *var_import_environ; +/* char *var_export_environ; +/* /* void mail_params_init() /* DESCRIPTION /* This module (actually the associated include file) define the names @@ -167,6 +170,9 @@ char *var_syslog_facility; char *var_relay_domains; char *var_fflush_domains; +char *var_import_environ; +char *var_export_environ; + /* check_myhostname - lookup hostname and validate */ static const char *check_myhostname(void) @@ -278,6 +284,8 @@ void mail_params_init() VAR_RCPT_DELIM, DEF_RCPT_DELIM, &var_rcpt_delim, 0, 1, VAR_RELAY_DOMAINS, DEF_RELAY_DOMAINS, &var_relay_domains, 0, 0, VAR_FFLUSH_DOMAINS, DEF_FFLUSH_DOMAINS, &var_fflush_domains, 0, 0, + VAR_EXPORT_ENVIRON, DEF_EXPORT_ENVIRON, &var_export_environ, 0, 0, + VAR_IMPORT_ENVIRON, DEF_IMPORT_ENVIRON, &var_import_environ, 0, 0, 0, }; static CONFIG_STR_FN_TABLE function_str_defaults_2[] = { diff --git a/postfix/src/global/mail_params.h b/postfix/src/global/mail_params.h index 53cbf5e4d..2235cabd6 100644 --- a/postfix/src/global/mail_params.h +++ b/postfix/src/global/mail_params.h @@ -1092,9 +1092,23 @@ extern int var_fflush_purge; #define DEF_FFLUSH_REFRESH "12h" extern int var_fflush_refresh; + /* + * Environmental management - what Postfix imports from the external world, + * and what Postfix exports to the external world. + */ +#define VAR_IMPORT_ENVIRON "import_environment" +#define DEF_IMPORT_ENVIRON "MAIL_CONFIG, TZ, XAUTHORITY, DISPLAY" +extern char *var_import_environ; + +#define VAR_EXPORT_ENVIRON "export_environment" +#define DEF_EXPORT_ENVIRON "TZ" +extern char *var_export_environ; + /* LICENSE /* .ad /* .fi +Unterminated comment + /* The Secure Mailer license must be distributed with this software. /* AUTHOR(S) /* Wietse Venema diff --git a/postfix/src/global/mail_stream.c b/postfix/src/global/mail_stream.c index 8680c026a..9cb5118ac 100644 --- a/postfix/src/global/mail_stream.c +++ b/postfix/src/global/mail_stream.c @@ -86,6 +86,7 @@ #include #include #include +#include /* Global library. */ @@ -93,6 +94,7 @@ #include #include #include +#include #include /* Application-specific. */ @@ -237,6 +239,7 @@ MAIL_STREAM *mail_stream_command(const char *command) { VSTREAM *stream; MAIL_STREAM *info; + ARGV *export_env; if (id_buf == 0) id_buf = vstring_alloc(10); @@ -245,10 +248,16 @@ MAIL_STREAM *mail_stream_command(const char *command) * Treat fork() failure as a transient problem. Treat bad handshake as a * permanent error. */ - while ((stream = vstream_popen(command, O_RDWR)) == 0) { + export_env = argv_split(var_export_environ, ", \t\r\n"); + while ((stream = vstream_popen(O_RDWR, + VSTREAM_POPEN_COMMAND, command, + VSTREAM_POPEN_EXPORT, export_env->argv, + VSTREAM_POPEN_END)) == 0) { msg_warn("fork: %m"); sleep(10); } + argv_free(export_env); + if (mail_scan(stream, "%s", id_buf) != 1) { vstream_pclose(stream); return (0); diff --git a/postfix/src/global/mail_version.h b/postfix/src/global/mail_version.h index f2fc3a596..46ba5a8be 100644 --- a/postfix/src/global/mail_version.h +++ b/postfix/src/global/mail_version.h @@ -15,7 +15,7 @@ * Version of this program. */ #define VAR_MAIL_VERSION "mail_version" -#define DEF_MAIL_VERSION "Snapshot-20001203" +#define DEF_MAIL_VERSION "Snapshot-20001208" extern char *var_mail_version; /* LICENSE diff --git a/postfix/src/global/pipe_command.c b/postfix/src/global/pipe_command.c index b86da9cad..8c9615a6f 100644 --- a/postfix/src/global/pipe_command.c +++ b/postfix/src/global/pipe_command.c @@ -42,6 +42,9 @@ /* Additional environment information, in the form of a null-terminated /* list of name, value, name, value, ... elements. By default only the /* command search path is initialized to _PATH_DEFPATH. +/* .IP "PIPE_CMD_EXPORT (char **)" +/* Null-terminated array with names of environment parameters +/* that can be exported. By default, everything is exported. /* .IP "PIPE_CMD_COPY_FLAGS (int)" /* Flags that are passed on to the \fImail_copy\fR() routine. /* The default flags value is 0 (zero). @@ -146,6 +149,7 @@ struct pipe_args { uid_t uid; /* privileges */ gid_t gid; /* privileges */ char **env; /* extra environment */ + char **export; /* exportable environment */ char *shell; /* command shell */ }; @@ -171,6 +175,7 @@ static void get_pipe_args(struct pipe_args * args, va_list ap) args->uid = var_default_uid; args->gid = var_default_gid; args->env = 0; + args->export = 0; args->shell = 0; pipe_command_maxtime = var_command_maxtime; @@ -214,6 +219,9 @@ static void get_pipe_args(struct pipe_args * args, va_list ap) case PIPE_CMD_ENV: args->env = va_arg(ap, char **); break; + case PIPE_CMD_EXPORT: + args->export = va_arg(ap, char **); + break; case PIPE_CMD_SHELL: args->shell = va_arg(ap, char *); break; @@ -384,7 +392,8 @@ int pipe_command(VSTREAM *src, VSTRING *why,...) * Environment plumbing. Always reset the command search path. XXX * That should probably be done by clean_env(). */ - clean_env(); + if (args.export) + clean_env(args.export); if (setenv("PATH", _PATH_DEFPATH, 1)) msg_fatal("%s: setenv: %m", myname); if (args.env) diff --git a/postfix/src/global/pipe_command.h b/postfix/src/global/pipe_command.h index 822167935..cf8d59892 100644 --- a/postfix/src/global/pipe_command.h +++ b/postfix/src/global/pipe_command.h @@ -37,6 +37,7 @@ #define PIPE_CMD_ENV 9 /* extra environment */ #define PIPE_CMD_SHELL 10 /* alternative shell */ #define PIPE_CMD_EOL 11 /* record delimiter */ +#define PIPE_CMD_EXPORT 12 /* exportable environment */ /* * Command completion status. diff --git a/postfix/src/global/split_addr.c b/postfix/src/global/split_addr.c index a52760fdf..d9db5777b 100644 --- a/postfix/src/global/split_addr.c +++ b/postfix/src/global/split_addr.c @@ -16,7 +16,7 @@ /* /* Reserved addresses are not split: postmaster, mailer-daemon, /* double-bounce. Addresses that begin with owner-, or addresses -/* that end in -request are not split, unless the owner_request_special +/* that end in -request are not split when the owner_request_special /* parameter is set. /* LICENSE /* .ad diff --git a/postfix/src/local/Makefile.in b/postfix/src/local/Makefile.in index 826c7e102..437e89f83 100644 --- a/postfix/src/local/Makefile.in +++ b/postfix/src/local/Makefile.in @@ -323,10 +323,6 @@ mailbox.o: ../../include/mymalloc.h mailbox.o: ../../include/stringops.h mailbox.o: ../../include/set_eugid.h mailbox.o: ../../include/mail_copy.h -mailbox.o: ../../include/safe_open.h -mailbox.o: ../../include/deliver_flock.h -mailbox.o: ../../include/myflock.h -mailbox.o: ../../include/dot_lockfile.h mailbox.o: ../../include/defer.h mailbox.o: ../../include/bounce.h mailbox.o: ../../include/sent.h @@ -339,6 +335,7 @@ mailbox.o: ../../include/recipient_list.h mailbox.o: ../../include/mail_proto.h mailbox.o: ../../include/iostuff.h mailbox.o: ../../include/mbox_open.h +mailbox.o: ../../include/safe_open.h mailbox.o: local.h mailbox.o: ../../include/tok822.h mailbox.o: ../../include/resolve_clnt.h diff --git a/postfix/src/local/command.c b/postfix/src/local/command.c index 6e5a215bd..23fffdf2f 100644 --- a/postfix/src/local/command.c +++ b/postfix/src/local/command.c @@ -89,6 +89,7 @@ int deliver_command(LOCAL_STATE state, USER_ATTR usr_attr, char *command) int copy_flags; char **cpp; char *cp; + ARGV *export_env; /* * Make verbose logging easier to understand. @@ -169,6 +170,8 @@ int deliver_command(LOCAL_STATE state, USER_ATTR usr_attr, char *command) for (cp = cpp[1]; *(cp += strspn(cp, var_cmd_exp_filter)) != 0;) *cp++ = '_'; + export_env = argv_split(var_export_environ, ", \t\r\n"); + cmd_status = pipe_command(state.msg_attr.fp, why, PIPE_CMD_UID, usr_attr.uid, PIPE_CMD_GID, usr_attr.gid, @@ -178,9 +181,11 @@ int deliver_command(LOCAL_STATE state, USER_ATTR usr_attr, char *command) PIPE_CMD_DELIVERED, state.msg_attr.delivered, PIPE_CMD_TIME_LIMIT, var_command_maxtime, PIPE_CMD_ENV, env->argv, + PIPE_CMD_EXPORT, export_env->argv, PIPE_CMD_SHELL, var_local_cmd_shell, PIPE_CMD_END); + argv_free(export_env); argv_free(env); /* diff --git a/postfix/src/local/local.c b/postfix/src/local/local.c index 241dcca64..981012b22 100644 --- a/postfix/src/local/local.c +++ b/postfix/src/local/local.c @@ -263,6 +263,9 @@ /* When delivering to an alias that has an owner- companion alias, /* set the envelope sender address to the right-hand side of the /* owner alias, instead using of the left-hand side address. +/* .IP \fBexport_environment\fR +/* List of names of environment parameters that can be exported +/* to non-Postfix processes. /* .IP \fBforward_path\fR /* Search list for .forward files. The names are subject to \fI$name\fR /* expansion. diff --git a/postfix/src/master/master.c b/postfix/src/master/master.c index 83e71c1a7..2967d914f 100644 --- a/postfix/src/master/master.c +++ b/postfix/src/master/master.c @@ -79,6 +79,10 @@ /* .SH Miscellaneous /* .ad /* .fi +/* .IP \fBimport_environment\fR +/* .IP \fBexport_environment\fR +/* Lists of names of environment parameters that can be imported +/* from (exported to) non-Postfix processes. /* .IP \fBmail_owner\fR /* The owner of the mail queue and of most Postfix processes. /* .IP \fBcommand_directory\fR @@ -144,6 +148,7 @@ #include #include #include +#include /* Global library. */ @@ -170,6 +175,7 @@ int main(int argc, char **argv) int fd_limit = open_limit(0); VSTRING *why; WATCHDOG *watchdog; + ARGV *import_env; /* * Initialize. @@ -184,12 +190,6 @@ int main(int argc, char **argv) if (getenv(CONF_ENV_DEBUG)) debug_me = 1; - /* - * Ad-hoc environment filter, to enforce consistent behavior whether - * Postfix is started by hand, or at system boot time. - */ - clean_env(); - /* * Don't die when a process goes away unexpectedly. */ @@ -278,6 +278,16 @@ int main(int argc, char **argv) * files. */ master_vars_init(); + + /* + * Environment import filter, to enforce consistent behavior whether + * Postfix is started by hand, or at system boot time. The argument list + * specifies what environment parameters to preserve. + */ + import_env = argv_split(var_import_environ, ", \t\r\n"); + clean_env(import_env->argv); + argv_free(import_env); + if ((inherited_limit = get_file_limit()) < (off_t) var_message_limit) { msg_warn("file size limit %lu < message_size_limit %lu -- reset", (unsigned long) inherited_limit, (unsigned long) var_message_limit); diff --git a/postfix/src/nqmgr/qmgr_active.c b/postfix/src/nqmgr/qmgr_active.c index 89d44dada..447825fac 100644 --- a/postfix/src/nqmgr/qmgr_active.c +++ b/postfix/src/nqmgr/qmgr_active.c @@ -102,12 +102,22 @@ #include #include #include +#include #include /* Application-specific. */ #include "qmgr.h" + /* + * A bunch of call-back routines. + */ +static void qmgr_active_done_2_bounce_flush(int, char *); +static void qmgr_active_done_2_generic(QMGR_MESSAGE *); +static void qmgr_active_done_3_defer_flush(int, char *); +static void qmgr_active_done_3_defer_warn(int, char *); +static void qmgr_active_done_3_generic(QMGR_MESSAGE *); + /* qmgr_active_corrupt - move corrupted file out of the way */ static void qmgr_active_corrupt(const char *queue_id) @@ -235,8 +245,6 @@ void qmgr_active_done(QMGR_MESSAGE *message) { char *myname = "qmgr_active_done"; struct stat st; - const char *path; - int delay; if (msg_verbose) msg_info("%s: %s", myname, message->queue_id); @@ -255,6 +263,9 @@ void qmgr_active_done(QMGR_MESSAGE *message) * Don't bounce when the bounce log is empty. The bounce process obviously * failed, and the delivery agent will have requested that the message be * deferred. + * + * Bounces are sent asynchronously to avoid stalling while the cleanup + * daemon waits for the qmgr to accept the "new mail" trigger. */ if (stat(mail_queue_path((VSTRING *) 0, MAIL_QUEUE_BOUNCE, message->queue_id), &st) == 0) { if (st.st_size == 0) { @@ -264,13 +275,43 @@ void qmgr_active_done(QMGR_MESSAGE *message) } else { if (msg_verbose) msg_info("%s: bounce %s", myname, message->queue_id); - message->flags |= bounce_flush(BOUNCE_FLAG_KEEP, - message->queue_name, - message->queue_id, - message->errors_to); + abounce_flush(BOUNCE_FLAG_KEEP, + message->queue_name, + message->queue_id, + message->errors_to, + qmgr_active_done_2_bounce_flush, + (char *) message); + return; } } + /* + * Asynchronous processing does not reach this point. + */ + qmgr_active_done_2_generic(message); +} + +/* qmgr_active_done_2_bounce_flush - process abounce_flush() status */ + +static void qmgr_active_done_2_bounce_flush(int status, char *context) +{ + QMGR_MESSAGE *message = (QMGR_MESSAGE *) context; + + /* + * Process abounce_flush() status and continue processing. + */ + message->flags |= status; + qmgr_active_done_2_generic(message); +} + +/* qmgr_active_done_2_generic - continue processing */ + +static void qmgr_active_done_2_generic(QMGR_MESSAGE *message) +{ + char *myname = "qmgr_active_done_2_generic"; + const char *path; + struct stat st; + /* * A delivery agent marks a queue file as corrupt by changing its * attributes, and by pretending that delivery was deferred. @@ -304,6 +345,9 @@ void qmgr_active_done(QMGR_MESSAGE *message) /* * If we get to this point we have tried all recipients for this message. * If the message is too old, try to bounce it. + * + * Bounces are sent asynchronously to avoid stalling while the cleanup + * daemon waits for the qmgr to accept the "new mail" trigger. */ #define HOUR 3600 #define DAY 86400 @@ -312,23 +356,67 @@ void qmgr_active_done(QMGR_MESSAGE *message) if (event_time() > message->arrival_time + var_max_queue_time * DAY) { if (msg_verbose) msg_info("%s: too old, bouncing %s", myname, message->queue_id); - message->flags = defer_flush(BOUNCE_FLAG_KEEP, - message->queue_name, - message->queue_id, - message->errors_to); + adefer_flush(BOUNCE_FLAG_KEEP, + message->queue_name, + message->queue_id, + message->errors_to, + qmgr_active_done_3_defer_flush, + (char *) message); + return; } else if (message->warn_time > 0 && event_time() > message->warn_time) { if (msg_verbose) msg_info("%s: sending defer warning for %s", myname, message->queue_id); - if (defer_warn(BOUNCE_FLAG_KEEP, - message->queue_name, - message->queue_id, - message->errors_to) == 0) { - qmgr_message_update_warn(message); - } + adefer_warn(BOUNCE_FLAG_KEEP, + message->queue_name, + message->queue_id, + message->errors_to, + qmgr_active_done_3_defer_warn, + (char *) message); + return; } } + /* + * Asynchronous processing does not reach this point. + */ + qmgr_active_done_3_generic(message); +} + +/* qmgr_active_done_3_defer_warn - continue after adefer_warn() completion */ + +static void qmgr_active_done_3_defer_warn(int status, char *context) +{ + QMGR_MESSAGE *message = (QMGR_MESSAGE *) context; + + /* + * Process adefer_warn() completion status and continue processing. + */ + if (status == 0) + qmgr_message_update_warn(message); + qmgr_active_done_3_generic(message); +} + +/* qmgr_active_done_3_defer_flush - continue after adefer_flush() completion */ + +static void qmgr_active_done_3_defer_flush(int status, char *context) +{ + QMGR_MESSAGE *message = (QMGR_MESSAGE *) context; + + /* + * Process adefer_flush() status and continue processing. + */ + message->flags = status; + qmgr_active_done_3_generic(message); +} + +/* qmgr_active_done_3_generic - continue processing */ + +static void qmgr_active_done_3_generic(QMGR_MESSAGE *message) +{ + char *myname = "qmgr_active_done_3_generic"; + int delay; + /* * Some recipients need to be tried again. Move the queue file time * stamps into the future by the amount of time that the message is diff --git a/postfix/src/pipe/pipe.c b/postfix/src/pipe/pipe.c index c26a60737..87aa58178 100644 --- a/postfix/src/pipe/pipe.c +++ b/postfix/src/pipe/pipe.c @@ -127,6 +127,9 @@ /* .SH Miscellaneous /* .ad /* .fi +/* .IP \fBexport_environment\fR +/* List of names of environment parameters that can be exported +/* to non-Postfix processes. /* .IP \fBmail_owner\fR /* The process privileges used while not running an external command. /* .SH "Resource controls" @@ -629,6 +632,7 @@ static int deliver_message(DELIVER_REQUEST *request, char *service, char **argv) ARGV *expanded_argv = 0; int deliver_status; int command_status; + ARGV *export_env; #define DELIVER_MSG_CLEANUP() { \ vstring_free(why); \ @@ -695,6 +699,7 @@ static int deliver_message(DELIVER_REQUEST *request, char *service, char **argv) dict_update(PIPE_DICT_TABLE, PIPE_DICT_SENDER, request->sender); dict_update(PIPE_DICT_TABLE, PIPE_DICT_NEXTHOP, request->nexthop); expanded_argv = expand_argv(attr.command, rcpt_list, request->data_size); + export_env = argv_split(var_export_environ, ", \t\r\n"); command_status = pipe_command(request->fp, why, PIPE_CMD_UID, attr.uid, @@ -704,7 +709,9 @@ static int deliver_message(DELIVER_REQUEST *request, char *service, char **argv) PIPE_CMD_ARGV, expanded_argv->argv, PIPE_CMD_TIME_LIMIT, conf.time_limit, PIPE_CMD_EOL, STR(attr.eol), + PIPE_CMD_EXPORT, export_env->argv, PIPE_CMD_END); + argv_free(export_env); deliver_status = eval_command_status(command_status, service, request, request->fp, vstring_str(why)); diff --git a/postfix/src/postdrop/postdrop.c b/postfix/src/postdrop/postdrop.c index 89907d040..f3b5faa0d 100644 --- a/postfix/src/postdrop/postdrop.c +++ b/postfix/src/postdrop/postdrop.c @@ -44,6 +44,9 @@ /* See the Postfix \fBmain.cf\fR file for syntax details and for /* default values. Use the \fBpostfix reload\fR command after a /* configuration change. +/* .IP \fBimport_environment\fR +/* List of names of environment parameters that can be imported +/* from non-Postfix processes. /* .IP \fBqueue_directory\fR /* Top-level directory of the Postfix queue. This is also the root /* directory of Postfix daemons that run chrooted. @@ -81,6 +84,7 @@ #include #include #include +#include /* Global library. */ @@ -153,6 +157,7 @@ int main(int argc, char **argv) }; char **expected; uid_t uid = getuid(); + ARGV *import_env; /* * Be consistent with file permissions. @@ -172,7 +177,9 @@ int main(int argc, char **argv) /* * Strip the environment so we don't have to trust the C library. */ - clean_env(); + import_env = argv_split(var_import_environ, ", \t\r\n"); + clean_env(import_env->argv); + argv_free(import_env); /* * Set up logging. Censor the process name: it is provided by the user. diff --git a/postfix/src/postlock/Makefile.in b/postfix/src/postlock/Makefile.in index 8f88fff7c..7e17af815 100644 --- a/postfix/src/postlock/Makefile.in +++ b/postfix/src/postlock/Makefile.in @@ -61,7 +61,6 @@ postlock.o: ../../include/vbuf.h postlock.o: ../../include/vstream.h postlock.o: ../../include/msg_vstream.h postlock.o: ../../include/iostuff.h -postlock.o: ../../include/safe_open.h postlock.o: ../../include/mail_params.h postlock.o: ../../include/dot_lockfile.h postlock.o: ../../include/deliver_flock.h @@ -71,3 +70,4 @@ postlock.o: ../../include/sys_exits.h postlock.o: ../../include/mbox_conf.h postlock.o: ../../include/argv.h postlock.o: ../../include/mbox_open.h +postlock.o: ../../include/safe_open.h diff --git a/postfix/src/qmgr/qmgr_active.c b/postfix/src/qmgr/qmgr_active.c index 89d44dada..447825fac 100644 --- a/postfix/src/qmgr/qmgr_active.c +++ b/postfix/src/qmgr/qmgr_active.c @@ -102,12 +102,22 @@ #include #include #include +#include #include /* Application-specific. */ #include "qmgr.h" + /* + * A bunch of call-back routines. + */ +static void qmgr_active_done_2_bounce_flush(int, char *); +static void qmgr_active_done_2_generic(QMGR_MESSAGE *); +static void qmgr_active_done_3_defer_flush(int, char *); +static void qmgr_active_done_3_defer_warn(int, char *); +static void qmgr_active_done_3_generic(QMGR_MESSAGE *); + /* qmgr_active_corrupt - move corrupted file out of the way */ static void qmgr_active_corrupt(const char *queue_id) @@ -235,8 +245,6 @@ void qmgr_active_done(QMGR_MESSAGE *message) { char *myname = "qmgr_active_done"; struct stat st; - const char *path; - int delay; if (msg_verbose) msg_info("%s: %s", myname, message->queue_id); @@ -255,6 +263,9 @@ void qmgr_active_done(QMGR_MESSAGE *message) * Don't bounce when the bounce log is empty. The bounce process obviously * failed, and the delivery agent will have requested that the message be * deferred. + * + * Bounces are sent asynchronously to avoid stalling while the cleanup + * daemon waits for the qmgr to accept the "new mail" trigger. */ if (stat(mail_queue_path((VSTRING *) 0, MAIL_QUEUE_BOUNCE, message->queue_id), &st) == 0) { if (st.st_size == 0) { @@ -264,13 +275,43 @@ void qmgr_active_done(QMGR_MESSAGE *message) } else { if (msg_verbose) msg_info("%s: bounce %s", myname, message->queue_id); - message->flags |= bounce_flush(BOUNCE_FLAG_KEEP, - message->queue_name, - message->queue_id, - message->errors_to); + abounce_flush(BOUNCE_FLAG_KEEP, + message->queue_name, + message->queue_id, + message->errors_to, + qmgr_active_done_2_bounce_flush, + (char *) message); + return; } } + /* + * Asynchronous processing does not reach this point. + */ + qmgr_active_done_2_generic(message); +} + +/* qmgr_active_done_2_bounce_flush - process abounce_flush() status */ + +static void qmgr_active_done_2_bounce_flush(int status, char *context) +{ + QMGR_MESSAGE *message = (QMGR_MESSAGE *) context; + + /* + * Process abounce_flush() status and continue processing. + */ + message->flags |= status; + qmgr_active_done_2_generic(message); +} + +/* qmgr_active_done_2_generic - continue processing */ + +static void qmgr_active_done_2_generic(QMGR_MESSAGE *message) +{ + char *myname = "qmgr_active_done_2_generic"; + const char *path; + struct stat st; + /* * A delivery agent marks a queue file as corrupt by changing its * attributes, and by pretending that delivery was deferred. @@ -304,6 +345,9 @@ void qmgr_active_done(QMGR_MESSAGE *message) /* * If we get to this point we have tried all recipients for this message. * If the message is too old, try to bounce it. + * + * Bounces are sent asynchronously to avoid stalling while the cleanup + * daemon waits for the qmgr to accept the "new mail" trigger. */ #define HOUR 3600 #define DAY 86400 @@ -312,23 +356,67 @@ void qmgr_active_done(QMGR_MESSAGE *message) if (event_time() > message->arrival_time + var_max_queue_time * DAY) { if (msg_verbose) msg_info("%s: too old, bouncing %s", myname, message->queue_id); - message->flags = defer_flush(BOUNCE_FLAG_KEEP, - message->queue_name, - message->queue_id, - message->errors_to); + adefer_flush(BOUNCE_FLAG_KEEP, + message->queue_name, + message->queue_id, + message->errors_to, + qmgr_active_done_3_defer_flush, + (char *) message); + return; } else if (message->warn_time > 0 && event_time() > message->warn_time) { if (msg_verbose) msg_info("%s: sending defer warning for %s", myname, message->queue_id); - if (defer_warn(BOUNCE_FLAG_KEEP, - message->queue_name, - message->queue_id, - message->errors_to) == 0) { - qmgr_message_update_warn(message); - } + adefer_warn(BOUNCE_FLAG_KEEP, + message->queue_name, + message->queue_id, + message->errors_to, + qmgr_active_done_3_defer_warn, + (char *) message); + return; } } + /* + * Asynchronous processing does not reach this point. + */ + qmgr_active_done_3_generic(message); +} + +/* qmgr_active_done_3_defer_warn - continue after adefer_warn() completion */ + +static void qmgr_active_done_3_defer_warn(int status, char *context) +{ + QMGR_MESSAGE *message = (QMGR_MESSAGE *) context; + + /* + * Process adefer_warn() completion status and continue processing. + */ + if (status == 0) + qmgr_message_update_warn(message); + qmgr_active_done_3_generic(message); +} + +/* qmgr_active_done_3_defer_flush - continue after adefer_flush() completion */ + +static void qmgr_active_done_3_defer_flush(int status, char *context) +{ + QMGR_MESSAGE *message = (QMGR_MESSAGE *) context; + + /* + * Process adefer_flush() status and continue processing. + */ + message->flags = status; + qmgr_active_done_3_generic(message); +} + +/* qmgr_active_done_3_generic - continue processing */ + +static void qmgr_active_done_3_generic(QMGR_MESSAGE *message) +{ + char *myname = "qmgr_active_done_3_generic"; + int delay; + /* * Some recipients need to be tried again. Move the queue file time * stamps into the future by the amount of time that the message is diff --git a/postfix/src/smtp/Makefile.in b/postfix/src/smtp/Makefile.in index 0e31ac857..8f97c6b58 100644 --- a/postfix/src/smtp/Makefile.in +++ b/postfix/src/smtp/Makefile.in @@ -117,6 +117,8 @@ smtp_chat.o: ../../include/mail_params.h smtp_chat.o: ../../include/mail_addr.h smtp_chat.o: ../../include/post_mail.h smtp_chat.o: ../../include/cleanup_user.h +smtp_chat.o: ../../include/mail_error.h +smtp_chat.o: ../../include/name_mask.h smtp_chat.o: smtp.h smtp_connect.o: smtp_connect.c smtp_connect.o: ../../include/sys_defs.h diff --git a/postfix/src/spawn/spawn.c b/postfix/src/spawn/spawn.c index 5c60409c1..597af070a 100644 --- a/postfix/src/spawn/spawn.c +++ b/postfix/src/spawn/spawn.c @@ -60,6 +60,9 @@ /* .SH Miscellaneous /* .ad /* .fi +/* .IP \fBexport_environment\fR +/* List of names of environment parameters that can be exported +/* to non-Postfix processes. /* .IP \fBmail_owner\fR /* The process privileges used while not running an external command. /* .SH Resource control @@ -229,6 +232,7 @@ static void spawn_service(VSTREAM *client_stream, char *service, char **argv) char *myname = "spawn_service"; static SPAWN_ATTR attr; WAIT_STATUS_T status; + ARGV *export_env; /* * This routine runs whenever a client connects to the UNIX-domain socket @@ -248,6 +252,7 @@ static void spawn_service(VSTREAM *client_stream, char *service, char **argv) /* * Execute the command. */ + export_env = argv_split(var_export_environ, ", \t\r\n"); status = spawn_command(SPAWN_CMD_STDIN, vstream_fileno(client_stream), SPAWN_CMD_STDOUT, vstream_fileno(client_stream), SPAWN_CMD_STDERR, vstream_fileno(client_stream), @@ -255,7 +260,9 @@ static void spawn_service(VSTREAM *client_stream, char *service, char **argv) SPAWN_CMD_GID, attr.gid, SPAWN_CMD_ARGV, attr.argv, SPAWN_CMD_TIME_LIMIT, attr.time_limit, + SPAWN_CMD_EXPORT, export_env->argv, SPAWN_CMD_END); + argv_free(export_env); /* * Warn about unsuccessful completion. diff --git a/postfix/src/util/Makefile.in b/postfix/src/util/Makefile.in index 5abc233a7..8d8c53b63 100644 --- a/postfix/src/util/Makefile.in +++ b/postfix/src/util/Makefile.in @@ -342,6 +342,8 @@ chroot_uid.o: chroot_uid.h clean_env.o: clean_env.c clean_env.o: sys_defs.h clean_env.o: msg.h +clean_env.o: argv.h +clean_env.o: safe.h clean_env.o: clean_env.h close_on_exec.o: close_on_exec.c close_on_exec.o: sys_defs.h @@ -715,8 +717,6 @@ mvect.o: mvect.h myflock.o: myflock.c myflock.o: sys_defs.h myflock.o: msg.h -myflock.o: vstring.h -myflock.o: vbuf.h myflock.o: myflock.h mymalloc.o: mymalloc.c mymalloc.o: sys_defs.h diff --git a/postfix/src/util/clean_env.c b/postfix/src/util/clean_env.c index aee035cca..4079e6d8f 100644 --- a/postfix/src/util/clean_env.c +++ b/postfix/src/util/clean_env.c @@ -6,11 +6,17 @@ /* SYNOPSIS /* #include /* -/* void clean_env() +/* void clean_env(export_list) +/* const char **export_list; /* DESCRIPTION /* clean_env() reduces the process environment to the bare minimum. -/* In the initial version, rules are hard-coded. This will be -/* made configurable. +/* The function takes a null-terminated list of arguments. +/* Each argument specifies the name of an environment variable +/* that should be preserved. +/* DIAGNOSTICS +/* Fatal error: out of memory. +/* SEE ALSO +/* safe_getenv(3), guarded getenv() /* LICENSE /* .ad /* .fi @@ -31,28 +37,27 @@ /* Utility library. */ #include +#include +#include #include /* clean_env - clean up the environment */ -void clean_env(void) +void clean_env(char **export_list) { - char *TZ; - char *DISPLAY; - char *XAUTHORITY; - char *HOME; - char *PURIFYOPTIONS; extern char **environ; + ARGV *save_list; + char *value; + char **cpp; /* - * Preserve selected environment variables. This list will be - * configurable. + * Preserve selected environment variables. */ - TZ = getenv("TZ"); - DISPLAY = getenv("DISPLAY"); - XAUTHORITY = getenv("XAUTHORITY"); - HOME = getenv("HOME"); - PURIFYOPTIONS = getenv("PURIFYOPTIONS"); + save_list = argv_alloc(10); + for (cpp = export_list; *cpp; cpp++) + if ((value = safe_getenv(*cpp)) != 0) + argv_add(save_list, *cpp, value, (char *) 0); + argv_terminate(save_list); /* * Truncate the process environment, if available. On some systems @@ -64,18 +69,12 @@ void clean_env(void) /* * Restore preserved environment variables. */ - if (TZ && setenv("TZ", TZ, 1)) - msg_fatal("setenv: %m"); - if (DISPLAY && setenv("DISPLAY", DISPLAY, 1)) - msg_fatal("setenv: %m"); - if (XAUTHORITY && setenv("XAUTHORITY", XAUTHORITY, 1)) - msg_fatal("setenv: %m"); - if (HOME && setenv("HOME", HOME, 1)) - msg_fatal("setenv: %m"); - if (PURIFYOPTIONS && setenv("PURIFYOPTIONS", PURIFYOPTIONS, 1)) - msg_fatal("setenv: %m"); + for (cpp = save_list->argv; *cpp; cpp += 2) + if (setenv(cpp[0], cpp[1], 1)) + msg_fatal("setenv: %m"); /* - * Update the process environment with configurable initial values. + * Cleanup. */ + argv_free(save_list); } diff --git a/postfix/src/util/clean_env.h b/postfix/src/util/clean_env.h index a837bf319..24cf70bea 100644 --- a/postfix/src/util/clean_env.h +++ b/postfix/src/util/clean_env.h @@ -14,7 +14,7 @@ /* * External interface. */ -extern void clean_env(void); +extern void clean_env(char **); /* LICENSE /* .ad diff --git a/postfix/src/util/spawn_command.c b/postfix/src/util/spawn_command.c index f20a66bd8..595dddbdc 100644 --- a/postfix/src/util/spawn_command.c +++ b/postfix/src/util/spawn_command.c @@ -34,6 +34,9 @@ /* Additional environment information, in the form of a null-terminated /* list of name, value, name, value, ... elements. By default only the /* command search path is initialized to _PATH_DEFPATH. +/* .IP "SPAWN_CMD_EXPORT (char **)" +/* Null-terminated array of names of environment parameters that can +/* be exported. By default, everything is exported. /* .IP "SPAWN_CMD_STDIN (int)" /* .IP "SPAWN_CMD_STDOUT (int)" /* .IP "SPAWN_CMD_STDERR (int)" @@ -105,6 +108,7 @@ struct spawn_args { uid_t uid; /* privileges */ gid_t gid; /* privileges */ char **env; /* extra environment */ + char **export; /* exportable environment */ char *shell; /* command shell */ int time_limit; /* command time limit */ }; @@ -127,6 +131,7 @@ static void get_spawn_args(struct spawn_args * args, int init_key, va_list ap) args->uid = (uid_t) - 1; args->gid = (gid_t) - 1; args->env = 0; + args->export = 0; args->shell = 0; args->time_limit = 0; @@ -168,6 +173,9 @@ static void get_spawn_args(struct spawn_args * args, int init_key, va_list ap) case SPAWN_CMD_ENV: args->env = va_arg(ap, char **); break; + case SPAWN_CMD_EXPORT: + args->export = va_arg(ap, char **); + break; case SPAWN_CMD_SHELL: args->shell = va_arg(ap, char *); break; @@ -245,7 +253,8 @@ WAIT_STATUS_T spawn_command(int key,...) * Environment plumbing. Always reset the command search path. XXX * That should probably be done by clean_env(). */ - clean_env(); + if (args.export) + clean_env(args.export); if (setenv("PATH", _PATH_DEFPATH, 1)) msg_fatal("%s: setenv: %m", myname); if (args.env) diff --git a/postfix/src/util/spawn_command.h b/postfix/src/util/spawn_command.h index b89887ede..9282528a6 100644 --- a/postfix/src/util/spawn_command.h +++ b/postfix/src/util/spawn_command.h @@ -25,6 +25,7 @@ #define SPAWN_CMD_TIME_LIMIT 8 /* time limit */ #define SPAWN_CMD_ENV 9 /* extra environment */ #define SPAWN_CMD_SHELL 10 /* alternative shell */ +#define SPAWN_CMD_EXPORT 11 /* exportable parameters */ extern WAIT_STATUS_T spawn_command(int,...); diff --git a/postfix/src/util/sys_defs.h b/postfix/src/util/sys_defs.h index 77bbbe9d6..cf315c46b 100644 --- a/postfix/src/util/sys_defs.h +++ b/postfix/src/util/sys_defs.h @@ -34,6 +34,7 @@ #define HAS_FLOCK_LOCK #define HAS_FCNTL_LOCK #define INTERNAL_LOCK MYFLOCK_STYLE_FLOCK +#define DEF_MAILBOX_LOCK "flock" #define HAS_SUN_LEN #define HAS_FSYNC #define HAS_DB @@ -62,11 +63,8 @@ #endif #if defined(NETBSD1) +#undef DEF_MAILBOX_LOCK #define DEF_MAILBOX_LOCK "flock, dotlock" -#endif - -#ifndef DEF_MAILBOX_LOCK -#define DEF_MAILBOX_LOCK "flock" #endif /* diff --git a/postfix/src/util/vstream.h b/postfix/src/util/vstream.h index 66f926a23..f38259b27 100644 --- a/postfix/src/util/vstream.h +++ b/postfix/src/util/vstream.h @@ -114,8 +114,7 @@ extern void vstream_control(VSTREAM *, int,...); extern VSTREAM *PRINTFLIKE(1, 2) vstream_printf(const char *,...); extern VSTREAM *PRINTFLIKE(2, 3) vstream_fprintf(VSTREAM *, const char *,...); -extern VSTREAM *vstream_popen(const char *, int); -extern VSTREAM *vstream_popen_vargs(int,...); +extern VSTREAM *vstream_popen(int,...); extern int vstream_pclose(VSTREAM *); #define vstream_ispipe(vp) ((vp)->pid != 0) @@ -128,6 +127,7 @@ extern int vstream_pclose(VSTREAM *); #define VSTREAM_POPEN_ENV 5 /* extra environment */ #define VSTREAM_POPEN_SHELL 6 /* alternative shell */ #define VSTREAM_POPEN_WAITPID_FN 7 /* child catcher, waitpid() compat. */ +#define VSTREAM_POPEN_EXPORT 8 /* exportable environment */ extern VSTREAM *vstream_vfprintf(VSTREAM *, const char *, va_list); diff --git a/postfix/src/util/vstream_popen.c b/postfix/src/util/vstream_popen.c index 23294f979..dad7b3062 100644 --- a/postfix/src/util/vstream_popen.c +++ b/postfix/src/util/vstream_popen.c @@ -6,28 +6,21 @@ /* SYNOPSIS /* #include /* -/* VSTREAM *vstream_popen(command, flags) -/* cont char *command; +/* VSTREAM *vstream_popen(flags, key, value, ...) /* int flags; +/* int key; /* /* int vstream_pclose(stream) /* VSTREAM *stream; -/* -/* VSTREAM *vstream_popen_vargs(key, value, ...) -/* int key; /* DESCRIPTION -/* vstream_popen() opens a one-way or two-way stream to the specified -/* \fIcommand\fR, which is executed by a child process. The \fIflags\fR +/* vstream_popen() opens a one-way or two-way stream to a user-specified +/* command, which is executed by a child process. The \fIflags\fR /* argument is as with vstream_fopen(). The child's standard input and /* standard output are redirected to the stream, which is based on a -/* socketpair or other suitable local IPC. -/* -/* vstream_popen_vargs() offers the user more control over the -/* child process and over how it is managed. The key argument -/* specifies what value will follow. pipe_command() takes a list -/* of (key, value) arguments, terminated by VSTREAM_POPEN_END. The -/* following is a listing of key codes together with the expected -/* value type. +/* socketpair or other suitable local IPC. vstream_popen() takes a list +/* of (key, value) arguments, terminated by VSTREAM_POPEN_END. The key +/* argument specifies what value will follow. The following is a listing +/* of key codes together with the expected value type. /* .RS /* .IP "VSTREAM_POPEN_COMMAND (char *)" /* Specifies the command to execute as a string. The string is @@ -44,6 +37,9 @@ /* Additional environment information, in the form of a null-terminated /* list of name, value, name, value, ... elements. By default only the /* command search path is initialized to _PATH_DEFPATH. +/* .IP "VSTREAM_POPEN_EXPORT (char **)" +/* Null-terminated array of names of environment parameters +/* that can be exported. By default, everything is exported. /* .IP "VSTREAM_POPEN_UID (int)" /* The user ID to execute the command as. The user ID must be non-zero. /* .IP "VSTREAM_POPEN_GID (int)" @@ -118,6 +114,7 @@ typedef struct VSTREAM_POPEN_ARGS { gid_t gid; int privileged; char **env; + char **export; char *shell; VSTREAM_WAITPID_FN waitpid_fn; } VSTREAM_POPEN_ARGS; @@ -138,6 +135,7 @@ static void vstream_parse_args(VSTREAM_POPEN_ARGS *args, va_list ap) args->gid = 0; args->privileged = 0; args->env = 0; + args->export = 0; args->shell = 0; args->waitpid_fn = 0; @@ -167,6 +165,9 @@ static void vstream_parse_args(VSTREAM_POPEN_ARGS *args, va_list ap) case VSTREAM_POPEN_ENV: args->env = va_arg(ap, char **); break; + case VSTREAM_POPEN_EXPORT: + args->export = va_arg(ap, char **); + break; case VSTREAM_POPEN_SHELL: args->shell = va_arg(ap, char *); break; @@ -186,11 +187,11 @@ static void vstream_parse_args(VSTREAM_POPEN_ARGS *args, va_list ap) msg_panic("%s: privileged gid", myname); } -/* vstream_popen_vargs - open stream to child process */ +/* vstream_popen - open stream to child process */ -VSTREAM *vstream_popen_vargs(int flags,...) +VSTREAM *vstream_popen(int flags,...) { - char *myname = "vstream_popen_vargs"; + char *myname = "vstream_popen"; VSTREAM_POPEN_ARGS args; va_list ap; VSTREAM *stream; @@ -233,7 +234,8 @@ VSTREAM *vstream_popen_vargs(int flags,...) * Environment plumbing. Always reset the command search path. XXX * That should probably be done by clean_env(). */ - clean_env(); + if (args.export) + clean_env(args.export); if (setenv("PATH", _PATH_DEFPATH, 1)) msg_fatal("%s: setenv: %m", myname); if (args.env) @@ -268,15 +270,6 @@ VSTREAM *vstream_popen_vargs(int flags,...) } } -/* vstream_popen - retro-compatible wrapper for new interface */ - -VSTREAM *vstream_popen(const char *command, int flags) -{ - return (vstream_popen_vargs(flags, - VSTREAM_POPEN_COMMAND, command, - VSTREAM_POPEN_END)); -} - /* vstream_pclose - close stream to child process */ int vstream_pclose(VSTREAM *stream)