X-Git-Url: https://git.exim.org/exim.git/blobdiff_plain/ba74fb8d95d2e9af2122e0a95c4d5334b4f0466c..4687a69c269ee3f2a7f0625e0147a503fd9d3d0b:/src/src/transports/pipe.c diff --git a/src/src/transports/pipe.c b/src/src/transports/pipe.c index 27422bd42..f8a1427b9 100644 --- a/src/src/transports/pipe.c +++ b/src/src/transports/pipe.c @@ -2,12 +2,15 @@ * Exim - an Internet mail transport agent * *************************************************/ +/* Copyright (c) The Exim maintainers 2020 - 2023 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ -/* Copyright (c) The Exim maintainers 2020 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ #include "../exim.h" + +#ifdef TRANSPORT_PIPE /* Remainder of file */ #include "pipe.h" #ifdef HAVE_SETCLASSRESOURCES @@ -88,31 +91,13 @@ BOOL pipe_transport_entry(transport_instance *tblock, address_item *addr) {retur /* Default private options block for the pipe transport. */ pipe_transport_options_block pipe_transport_option_defaults = { - NULL, /* cmd */ - NULL, /* allow_commands */ - NULL, /* environment */ - US"/bin:/usr/bin", /* path */ - NULL, /* message_prefix (reset in init if not bsmtp) */ - NULL, /* message_suffix (ditto) */ - US mac_expanded_string(EX_TEMPFAIL) ":" /* temp_errors */ - mac_expanded_string(EX_CANTCREAT), - NULL, /* check_string */ - NULL, /* escape_string */ - 022, /* umask */ - 20480, /* max_output */ - 60*60, /* timeout */ - 0, /* options */ - FALSE, /* force_command */ - FALSE, /* freeze_exec_fail */ - FALSE, /* freeze_signal */ - FALSE, /* ignore_status */ - FALSE, /* permit_coredump */ - FALSE, /* restrict_to_path */ - FALSE, /* timeout_defer */ - FALSE, /* use_shell */ - FALSE, /* use_bsmtp */ - FALSE, /* use_classresources */ - FALSE /* use_crlf */ + .path = US"/bin:/usr/bin", + .temp_errors = US mac_expanded_string(EX_TEMPFAIL) ":" + mac_expanded_string(EX_CANTCREAT), + .umask = 022, + .max_output = 20480, + .timeout = 60*60, + /* all others null/zero/false */ }; @@ -144,13 +129,6 @@ pipe_transport_setup(transport_instance *tblock, address_item *addrlist, pipe_transport_options_block *ob = (pipe_transport_options_block *)(tblock->options_block); -addrlist = addrlist; /* Keep compiler happy */ -dummy = dummy; -uid = uid; -gid = gid; -errmsg = errmsg; -ob = ob; - #ifdef HAVE_SETCLASSRESOURCES if (ob->use_classresources) { @@ -285,12 +263,12 @@ if (ob->allow_commands && ob->use_shell) driver options. Only one of body_only and headers_only can be set. */ ob->options |= - (tblock->body_only? topt_no_headers : 0) | - (tblock->headers_only? topt_no_body : 0) | - (tblock->return_path_add? topt_add_return_path : 0) | - (tblock->delivery_date_add? topt_add_delivery_date : 0) | - (tblock->envelope_to_add? topt_add_envelope_to : 0) | - (ob->use_crlf? topt_use_crlf : 0); + (tblock->body_only ? topt_no_headers : 0) + | (tblock->headers_only ? topt_no_body : 0) + | (tblock->return_path_add ? topt_add_return_path : 0) + | (tblock->delivery_date_add ? topt_add_delivery_date : 0) + | (tblock->envelope_to_add ? topt_add_envelope_to : 0) + | (ob->use_crlf ? topt_use_crlf : 0); } @@ -316,9 +294,9 @@ Returns: TRUE if all went well; otherwise an error will be */ static BOOL -set_up_direct_command(const uschar ***argvptr, uschar *cmd, - BOOL expand_arguments, int expand_fail, address_item *addr, uschar *tname, - pipe_transport_options_block *ob) +set_up_direct_command(const uschar *** argvptr, const uschar * cmd, + BOOL expand_arguments, int expand_fail, address_item * addr, uschar * tname, + pipe_transport_options_block * ob) { BOOL permitted = FALSE; const uschar **argv; @@ -328,8 +306,9 @@ call the common function for creating an argument list and expanding the items if necessary. If it fails, this function fails (error information is in the addresses). */ -if (!transport_set_up_command(argvptr, cmd, expand_arguments, expand_fail, - addr, string_sprintf("%.50s transport", tname), NULL)) +if (!transport_set_up_command(argvptr, cmd, + expand_arguments ? TSUC_EXPAND_ARGS : 0, + expand_fail, addr, string_sprintf("%.50s transport", tname), NULL)) return FALSE; /* Point to the set-up arguments. */ @@ -338,6 +317,7 @@ argv = *argvptr; /* If allow_commands is set, see if the command is in the permitted list. */ +GET_OPTION("allow_commands"); if (ob->allow_commands) { int sep = 0; @@ -391,10 +371,11 @@ for it. */ if (argv[0][0] != '/') { int sep = 0; - uschar *p; - const uschar *listptr = expand_string(ob->path); + uschar * p; - while ((p = string_nextinlist(&listptr, &sep, NULL, 0))) + GET_OPTION("path"); + for (const uschar * listptr = expand_string(ob->path); + p = string_nextinlist(&listptr, &sep, NULL, 0); ) { struct stat statbuf; sprintf(CS big_buffer, "%.256s/%.256s", p, argv[0]); @@ -437,12 +418,12 @@ Returns: TRUE if all went well; otherwise an error will be */ static BOOL -set_up_shell_command(const uschar ***argvptr, uschar *cmd, - BOOL expand_arguments, int expand_fail, address_item *addr, uschar *tname) +set_up_shell_command(const uschar *** argvptr, const uschar * cmd, + BOOL expand_arguments, int expand_fail, address_item * addr, uschar * tname) { const uschar **argv; -*argvptr = argv = store_get((4)*sizeof(uschar *), FALSE); +*argvptr = argv = store_get((4)*sizeof(uschar *), GET_UNTAINTED); argv[0] = US"/bin/sh"; argv[1] = US"-c"; @@ -476,16 +457,19 @@ if (expand_arguments) for (address_item * ad = addr; ad; ad = ad->next) { + DEBUG(D_transport) if (is_tainted(ad->address)) + debug_printf("tainted element '%s' from $pipe_addresses\n", ad->address); + /*XXX string_append_listele() ? */ if (ad != addr) g = string_catn(g, US" ", 1); g = string_cat(g, ad->address); } g = string_cat(g, q); - argv[2] = (cmd = string_from_gstring(g)) ? expand_string(cmd) : NULL; + argv[2] = (cmd = string_from_gstring(g)) ? expand_cstring(cmd) : NULL; } else - argv[2] = expand_string(cmd); + argv[2] = expand_cstring(cmd); f.enable_dollar_recipients = FALSE; @@ -538,11 +522,12 @@ pipe_transport_options_block *ob = int timeout = ob->timeout; BOOL written_ok = FALSE; BOOL expand_arguments; -const uschar **argv; -uschar *envp[50]; -const uschar *envlist = ob->environment; -uschar *cmd, *ss; -uschar *eol = ob->use_crlf ? US"\r\n" : US"\n"; +const uschar ** argv; +uschar * envp[50]; +const uschar * envlist = ob->environment; +const uschar * cmd; +uschar * ss; +uschar * eol = ob->use_crlf ? US"\r\n" : US"\n"; transport_ctx tctx = { .tblock = tblock, .addr = addr, @@ -569,6 +554,7 @@ if (testflag(addr, af_pfr) && addr->local_part[0] == '|') { /* Enables expansion of $address_pipe into separate arguments */ setflag(addr, af_force_command); + GET_OPTION("commsnd"); cmd = ob->cmd; expand_arguments = TRUE; expand_fail = PANIC; @@ -576,21 +562,21 @@ if (testflag(addr, af_pfr) && addr->local_part[0] == '|') else { cmd = addr->local_part + 1; - while (isspace(*cmd)) cmd++; + Uskip_whitespace(&cmd); expand_arguments = testflag(addr, af_expand_pipe); expand_fail = FAIL; } else { + GET_OPTION("commsnd"); cmd = ob->cmd; expand_arguments = TRUE; expand_fail = PANIC; } /* If no command has been supplied, we are in trouble. - * We also check for an empty string since it may be - * coming from addr->local_part[0] == '|' - */ +We also check for an empty string since it may be +coming from addr->local_part[0] == '|' */ if (!cmd || !*cmd) { @@ -601,6 +587,7 @@ if (!cmd || !*cmd) } if (is_tainted(cmd)) { + DEBUG(D_transport) debug_printf("cmd '%s' is tainted\n", cmd); addr->message = string_sprintf("Tainted '%s' (command " "for %s transport) not permitted", cmd, tblock->name); addr->transport_return = PANIC; @@ -659,15 +646,17 @@ envp[envcount++] = string_sprintf("QUALIFY_DOMAIN=%s", qualify_domain_sender); envp[envcount++] = string_sprintf("SENDER=%s", sender_address); envp[envcount++] = US"SHELL=/bin/sh"; -if (addr->host_list != NULL) +if (addr->host_list) envp[envcount++] = string_sprintf("HOST=%s", addr->host_list->name); -if (f.timestamps_utc) envp[envcount++] = US"TZ=UTC"; -else if (timezone_string != NULL && timezone_string[0] != 0) +if (f.timestamps_utc) + envp[envcount++] = US"TZ=UTC"; +else if (timezone_string && timezone_string[0]) envp[envcount++] = string_sprintf("TZ=%s", timezone_string); /* Add any requested items */ +GET_OPTION("environment"); if (envlist) if (!(envlist = expand_cstring(envlist))) { @@ -814,9 +803,10 @@ transport_count = 0; /* First write any configured prefix information */ +GET_OPTION("message_prefix"); if (ob->message_prefix) { - uschar *prefix = expand_string(ob->message_prefix); + uschar * prefix = expand_string(ob->message_prefix); if (!prefix) { addr->transport_return = f.search_find_defer? DEFER : PANIC; @@ -856,9 +846,10 @@ if (!transport_write_message(&tctx, 0)) /* Now any configured suffix */ +GET_OPTION("message_suffix"); if (ob->message_suffix) { - uschar *suffix = expand_string(ob->message_suffix); + uschar * suffix = expand_string(ob->message_suffix); if (!suffix) { addr->transport_return = f.search_find_defer? DEFER : PANIC; @@ -1142,4 +1133,5 @@ return FALSE; } #endif /*!MACRO_PREDEF*/ +#endif /*TRASPORT_PIPE*/ /* End of transport/pipe.c */