X-Git-Url: https://git.netwichtig.de/gitweb/?a=blobdiff_plain;f=src%2Fsrc%2Fdeliver.c;h=05494dd8b74b52eb3c04d0e7eeb110e6d403aa18;hb=81a559c80ccd6a0354b5485720c0205a69289fb5;hp=7b794720fecf47536eb6458eeb46669104009ab6;hpb=fa7b17bdbc8c055c475a50791627cd75d257f4f3;p=user%2Fhenk%2Fcode%2Fexim.git diff --git a/src/src/deliver.c b/src/src/deliver.c index 7b794720f..05494dd8b 100644 --- a/src/src/deliver.c +++ b/src/src/deliver.c @@ -144,7 +144,7 @@ Returns: a pointer to an initialized address_item address_item * deliver_make_addr(uschar *address, BOOL copy) { -address_item *addr = store_get(sizeof(address_item)); +address_item *addr = store_get(sizeof(address_item), FALSE); *addr = address_defaults; if (copy) address = string_copy(address); addr->address = address; @@ -155,47 +155,6 @@ return addr; -/************************************************/ -/* Set router-assigned variables, forgetting any previous. -Return FALSE on failure */ - -static BOOL -set_router_vars(gstring * g_varlist) -{ -const uschar * varlist; -int sep = 0; - -router_var = NULL; -if (!g_varlist) return TRUE; -varlist = CUS string_from_gstring(g_varlist); - -/* Walk the varlist, creating variables */ - -for (uschar * ele; (ele = string_nextinlist(&varlist, &sep, NULL, 0)); ) - { - const uschar * assignment = ele; - int esep = '='; - uschar * name = string_nextinlist(&assignment, &esep, NULL, 0); - tree_node * node, ** root = &router_var; - - /* Variable name must exist and start "r_". */ - - if (!name || name[0] != 'r' || name[1] != '_' || !name[2]) - return FALSE; - name += 2; - - if (!(node = tree_search(*root, name))) - { - node = store_get(sizeof(tree_node) + Ustrlen(name)); - Ustrcpy(node->name, name); - (void)tree_insertnode(root, node); - } - node->data.ptr = US assignment; - } -return TRUE; -} - - /************************************************* * Set expansion values for an address * *************************************************/ @@ -239,7 +198,7 @@ deliver_recipients = addr; deliver_address_data = addr->prop.address_data; deliver_domain_data = addr->prop.domain_data; deliver_localpart_data = addr->prop.localpart_data; -set_router_vars(addr->prop.set); /*XXX failure cases? */ +router_var = addr->prop.variables; /* These may be unset for multiple addresses */ @@ -1064,7 +1023,8 @@ splitting is done; in those cases use the original field. */ else { - uschar * cmp = g->s + g->ptr; + uschar * cmp; + int off = g->ptr; /* start of the "full address" */ if (addr->local_part) { @@ -1086,6 +1046,7 @@ else of all, do a caseless comparison; if this succeeds, do a caseful comparison on the local parts. */ + cmp = g->s + off; /* only now, as rebuffer likely done */ string_from_gstring(g); /* ensure nul-terminated */ if ( strcmpic(cmp, topaddr->address) == 0 && Ustrncmp(cmp, topaddr->address, Ustrchr(cmp, '@') - cmp) == 0 @@ -1178,7 +1139,7 @@ void delivery_log(int flags, address_item * addr, int logchar, uschar * msg) { gstring * g; /* Used for a temporary, expanding buffer, for building log lines */ -void * reset_point; /* released afterwards. */ +rmark reset_point; /* Log the delivery on the main log. We use an extensible string to build up the log line, and reset the store afterwards. Remote deliveries should always @@ -1190,7 +1151,8 @@ pointer to a single host item in their host list, for use by the transport. */ lookup_dnssec_authenticated = NULL; #endif -g = reset_point = string_get(256); +reset_point = store_mark(); +g = string_get_tainted(256, TRUE); /* addrs will be tainted, so avoid copy */ if (msg) g = string_append(g, 2, host_and_ident(TRUE), US" "); @@ -1358,14 +1320,12 @@ static void deferral_log(address_item * addr, uschar * now, int logflags, uschar * driver_name, uschar * driver_kind) { -gstring * g; -void * reset_point; +rmark reset_point = store_mark(); +gstring * g = string_get(256); /* Build up the line that is used for both the message log and the main log. */ -g = reset_point = string_get(256); - /* Create the address string for logging. Must not do this earlier, because an OK result may be changed to FAIL when a pipe returns text. */ @@ -1437,8 +1397,8 @@ return; static void failure_log(address_item * addr, uschar * driver_kind, uschar * now) { -void * reset_point; -gstring * g = reset_point = string_get(256); +rmark reset_point = store_mark(); +gstring * g = string_get(256); #ifndef DISABLE_EVENT /* Message failures for which we will send a DSN get their event raised @@ -1831,7 +1791,7 @@ if (format) gstring * g; va_start(ap, format); - g = string_vformat(NULL, TRUE, CS format, ap); + g = string_vformat(NULL, SVFMT_EXTEND|SVFMT_REBUFFER, CS format, ap); va_end(ap); addr->message = string_from_gstring(g); } @@ -2093,10 +2053,10 @@ Returns: TRUE if previously delivered by the transport static BOOL previously_transported(address_item *addr, BOOL testing) { -(void)string_format(big_buffer, big_buffer_size, "%s/%s", +uschar * s = string_sprintf("%s/%s", addr->unique + (testflag(addr, af_homonym)? 3:0), addr->transport->name); -if (tree_search(tree_nonrecipients, big_buffer) != 0) +if (tree_search(tree_nonrecipients, s) != 0) { DEBUG(D_deliver|D_route|D_transport) debug_printf("%s was previously delivered (%s transport): discarded\n", @@ -2796,7 +2756,7 @@ while (addr_local) f.disable_logging = FALSE; /* Jic */ addr->message = addr->router ? string_sprintf("No transport set by %s router", addr->router->name) - : string_sprintf("No transport set by system filter"); + : US"No transport set by system filter"; post_process_one(addr, DEFER, logflags, EXIM_DTYPE_TRANSPORT, 0); continue; } @@ -3107,7 +3067,7 @@ while (addr_local) else for (addr2 = addr; addr2; addr2 = addr2->next) if (addr2->transport_return == OK) { - addr3 = store_get(sizeof(address_item)); + addr3 = store_get(sizeof(address_item), FALSE); *addr3 = *addr2; addr3->next = NULL; addr3->shadow_message = US &addr2->shadow_message; @@ -3505,7 +3465,7 @@ while (!done) if (!r || !(*ptr & rf_delete)) { - r = store_get(sizeof(retry_item)); + r = store_get(sizeof(retry_item), FALSE); r->next = addr->retries; addr->retries = r; r->flags = *ptr++; @@ -3688,7 +3648,7 @@ while (!done) if (*ptr) { - h = store_get(sizeof(host_item)); + h = store_get(sizeof(host_item), FALSE); h->name = string_copy(ptr); while (*ptr++); h->address = string_copy(ptr); @@ -4272,7 +4232,7 @@ set up, do so. */ if (!parlist) { - parlist = store_get(remote_max_parallel * sizeof(pardata)); + parlist = store_get(remote_max_parallel * sizeof(pardata), FALSE); for (poffset = 0; poffset < remote_max_parallel; poffset++) parlist[poffset].pid = 0; } @@ -5158,7 +5118,7 @@ where they are locally interpreted. [The new draft "821" is more explicit on this, Jan 1999.] We know the syntax is valid, so this can be done by simply removing quoting backslashes and any unquoted doublequotes. */ -t = addr->cc_local_part = store_get(len+1); +t = addr->cc_local_part = store_get(len+1, is_tainted(address)); while(len-- > 0) { int c = *address++; @@ -5201,7 +5161,7 @@ if (percent_hack_domains) if (new_address) { - address_item *new_parent = store_get(sizeof(address_item)); + address_item *new_parent = store_get(sizeof(address_item), FALSE); *new_parent = *addr; addr->parent = new_parent; new_parent->child_count = 1; @@ -6069,8 +6029,8 @@ else if (system_filter && process_recipients != RECIP_FAIL_TIMEOUT) if (addr_new) { - int uid = (system_filter_uid_set)? system_filter_uid : geteuid(); - int gid = (system_filter_gid_set)? system_filter_gid : getegid(); + int uid = system_filter_uid_set ? system_filter_uid : geteuid(); + int gid = system_filter_gid_set ? system_filter_gid : getegid(); /* The text "system-filter" is tested in transport_set_up_command() and in set_up_shell_command() in the pipe transport, to enable them to permit @@ -6144,6 +6104,9 @@ else if (system_filter && process_recipients != RECIP_FAIL_TIMEOUT) if (!tmp) p->message = string_sprintf("failed to expand \"%s\" as a " "system filter transport name", tpname); + if (is_tainted(tmp)) + p->message = string_sprintf("attempt to used tainted value '%s' for" + "transport '%s' as a system filter", tmp, tpname); tpname = tmp; } else @@ -6452,10 +6415,8 @@ while (addr_new) /* Loop until all addresses dealt with */ keep piling '>' characters on the front. */ if (addr->address[0] == '>') - { while (tree_search(tree_duplicates, addr->unique)) addr->unique = string_sprintf(">%s", addr->unique); - } else if ((tnode = tree_search(tree_duplicates, addr->unique))) { @@ -6773,7 +6734,7 @@ while (addr_new) /* Loop until all addresses dealt with */ (void)post_process_one(addr, DEFER, LOG_MAIN, EXIM_DTYPE_ROUTER, 0); /* For remote-retry errors (here and just above) that we've not yet - hit the rery time, use the error recorded in the retry database + hit the retry time, use the error recorded in the retry database as info in the warning message. This lets us send a message even when we're not failing on a fresh attempt. We assume that this info is not sensitive. */ @@ -6863,8 +6824,8 @@ while (addr_new) /* Loop until all addresses dealt with */ &addr_succeed, v_none)) == DEFER) retry_add_item(addr, addr->router->retry_use_local_part - ? string_sprintf("R:%s@%s", addr->local_part, addr->domain) - : string_sprintf("R:%s", addr->domain), + ? string_sprintf("R:%s@%s", addr->local_part, addr->domain) + : string_sprintf("R:%s", addr->domain), 0); /* Otherwise, if there is an existing retry record in the database, add @@ -7359,7 +7320,7 @@ for (address_item * a = addr_succeed; a; a = a->next) { /* copy and relink address_item and send report with all of them at once later */ address_item * addr_next = addr_senddsn; - addr_senddsn = store_get(sizeof(address_item)); + addr_senddsn = store_get(sizeof(address_item), FALSE); *addr_senddsn = *a; addr_senddsn->next = addr_next; } @@ -8323,13 +8284,9 @@ else if (addr_defer != (address_item *)(+1)) /* List the addresses, with error information if allowed */ - /* store addr_defer for machine readable part */ - address_item *addr_dsndefer = addr_defer; fputc('\n', f); - while (addr_defer) + for (address_item * addr = addr_defer; addr; addr = addr->next) { - address_item *addr = addr_defer; - addr_defer = addr->next; if (print_address_information(addr, f, US" ", US"\n ", US"")) print_address_error(addr, f, US"Delay reason: "); fputc('\n', f); @@ -8372,16 +8329,16 @@ else if (addr_defer != (address_item *)(+1)) } fputc('\n', f); - for ( ; addr_dsndefer; addr_dsndefer = addr_dsndefer->next) + for (address_item * addr = addr_defer; addr; addr = addr->next) { host_item * hu; - print_dsn_addr_action(f, addr_dsndefer, US"delayed", US"4.0.0"); + print_dsn_addr_action(f, addr, US"delayed", US"4.0.0"); - if ((hu = addr_dsndefer->host_used) && hu->name) + if ((hu = addr->host_used) && hu->name) { fprintf(f, "Remote-MTA: dns; %s\n", hu->name); - print_dsn_diagnostic_code(addr_dsndefer, f); + print_dsn_diagnostic_code(addr, f); } fputc('\n', f); }