X-Git-Url: https://git.exim.org/exim.git/blobdiff_plain/2be324ee17454ae5c5a32a3533aced861d103074..805fd869d551c36d1d77ab2b292a7008d643ca79:/src/src/exim.c diff --git a/src/src/exim.c b/src/src/exim.c index 3f1e153fd..810550dd5 100644 --- a/src/src/exim.c +++ b/src/src/exim.c @@ -2,7 +2,7 @@ * Exim - an Internet mail transport agent * *************************************************/ -/* Copyright (c) University of Cambridge 1995 - 2017 */ +/* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ @@ -187,7 +187,15 @@ DEBUG(D_process_info) debug_printf("set_process_info: %s", process_info); va_end(ap); } +/*********************************************** +* Handler for SIGTERM * +***********************************************/ +static void +term_handler(int sig) +{ + exit(1); +} /************************************************* @@ -543,7 +551,7 @@ close_unwanted(void) if (smtp_input) { #ifdef SUPPORT_TLS - tls_close(TRUE, FALSE); /* Shut down the TLS library */ + tls_close(TRUE, TLS_NO_SHUTDOWN); /* Shut down the TLS library */ #endif (void)close(fileno(smtp_in)); (void)close(fileno(smtp_out)); @@ -832,6 +840,9 @@ fprintf(f, "Support for:"); #ifdef WITH_CONTENT_SCAN fprintf(f, " Content_Scanning"); #endif +#ifdef SUPPORT_DANE + fprintf(f, " DANE"); +#endif #ifndef DISABLE_DKIM fprintf(f, " DKIM"); #endif @@ -872,12 +883,12 @@ fprintf(f, "Support for:"); #ifdef EXPERIMENTAL_SRS fprintf(f, " Experimental_SRS"); #endif +#ifdef EXPERIMENTAL_ARC + fprintf(f, " Experimental_ARC"); +#endif #ifdef EXPERIMENTAL_BRIGHTMAIL fprintf(f, " Experimental_Brightmail"); #endif -#ifdef EXPERIMENTAL_DANE - fprintf(f, " Experimental_DANE"); -#endif #ifdef EXPERIMENTAL_DCC fprintf(f, " Experimental_DCC"); #endif @@ -1295,32 +1306,6 @@ exit(EXIT_FAILURE); * Validate that the macros given are okay * *************************************************/ -#ifdef WHITELIST_D_MACROS -static void -wlist_check(uschar * name, uschar * val, void * ctx) -{ -uschar ** w, ** whites = ctx; -unsigned len; -int n; - -for (w = whites; *w; ++w) - if (Ustrcmp(*w, name) == 0) break; -if (*w) - { - if (!val || !*val) return; - len = Ustrlen(val); - if ((n = pcre_exec(regex_whitelisted_macro, NULL, CS val, len, - 0, PCRE_EOPT, NULL, 0)) >= 0) - return; - if (n != PCRE_ERROR_NOMATCH) - debug_printf("macros_trusted checking %s returned %d\n", name, n); - } -*whites = NULL; -return; -} -#endif - - /* Typically, Exim will drop privileges if macros are supplied. In some cases, we want to not do so. @@ -1333,7 +1318,7 @@ macros_trusted(BOOL opt_D_used) { #ifdef WHITELIST_D_MACROS macro_item *m; -uschar *whitelisted, *end, *p, **whites; +uschar *whitelisted, *end, *p, **whites, **w; int white_count, i, n; size_t len; BOOL prev_char_item, found; @@ -1396,9 +1381,32 @@ for (p = whitelisted, i = 0; (p != end) && (i < white_count); ++p) } whites[i] = NULL; -tree_walk(tree_macros, wlist_check, whites); -if (!*whites) return FALSE; - +/* The list of commandline macros should be very short. +Accept the N*M complexity. */ +for (m = macros_user; m; m = m->next) if (m->command_line) + { + found = FALSE; + for (w = whites; *w; ++w) + if (Ustrcmp(*w, m->name) == 0) + { + found = TRUE; + break; + } + if (!found) + return FALSE; + if (!m->replacement) + continue; + if ((len = m->replen) == 0) + continue; + n = pcre_exec(regex_whitelisted_macro, NULL, CS m->replacement, len, + 0, PCRE_EOPT, NULL, 0); + if (n < 0) + { + if (n != PCRE_ERROR_NOMATCH) + debug_printf("macros_trusted checking %s returned %d\n", m->name, n); + return FALSE; + } + } DEBUG(D_any) debug_printf("macros_trusted overridden to true by whitelisting\n"); return TRUE; #endif @@ -1430,10 +1438,7 @@ len = Ustrlen(big_buffer); if (isupper(big_buffer[0])) { if (macro_read_assignment(big_buffer)) - { - uschar * s = Ustrchr(big_buffer, '='); - printf("Defined macro '%.*s'\n", s - big_buffer, big_buffer); - } + printf("Defined macro '%s'\n", mlast->name); } else if ((line = expand_string(big_buffer))) printf("%s\n", CS line); @@ -1627,6 +1632,8 @@ testing harness; do a fast initial check, and then the whole thing. */ running_in_test_harness = *running_status == '<' && Ustrcmp(running_status, "<<>>") == 0; +if (running_in_test_harness) + debug_store = TRUE; /* The C standard says that the equivalent of setlocale(LC_ALL, "C") is obeyed at the start of a program; however, it seems that some environments do not @@ -1679,6 +1686,10 @@ descriptive text. */ set_process_info("initializing"); os_restarting_signal(SIGUSR1, usr1_handler); +/* If running in a dockerized environment, the TERM signal is only +delegated to the PID 1 if we request it by setting an signal handler */ +if (getpid() == 1) signal(SIGTERM, term_handler); + /* SIGHUP is used to get the daemon to reconfigure. It gets set as appropriate in the daemon code. For the rest of Exim's uses, we ignore it. */ @@ -2428,11 +2439,12 @@ for (i = 1; i < argc; i++) while (isspace(*s)) s++; } - if (macro_search(name)) - { - fprintf(stderr, "exim: duplicated -D in command line\n"); - exit(EXIT_FAILURE); - } + for (m = macros_user; m; m = m->next) + if (Ustrcmp(m->name, name) == 0) + { + fprintf(stderr, "exim: duplicated -D in command line\n"); + exit(EXIT_FAILURE); + } m = macro_create(name, s, TRUE); @@ -2441,8 +2453,8 @@ for (i = 1; i < argc; i++) fprintf(stderr, "exim: too many -D options on command line\n"); exit(EXIT_FAILURE); } - clmacros[clmacro_count++] = string_sprintf("-D%s=%s", - m->tnode.name, m->tnode.data.ptr); + clmacros[clmacro_count++] = string_sprintf("-D%s=%s", m->name, + m->replacement); } #endif break; @@ -4079,8 +4091,11 @@ if (((debug_selector & D_any) != 0 || LOGGING(arguments)) Ustrcpy(p, "cwd= (failed)"); Ustrncpy(p + 4, initial_cwd, big_buffer_size-5); + p += 4 + Ustrlen(initial_cwd); + /* in case p is near the end and we don't provide enough space for + * string_format to be willing to write. */ + *p = '\0'; - while (*p) p++; (void)string_format(p, big_buffer_size - (p - big_buffer), " %d args:", argc); while (*p) p++; for (i = 0; i < argc; i++) @@ -4993,7 +5008,7 @@ if (expansion_test) /* Only admin users may see config-file macros this way */ - if (!admin_user) tree_macros = NULL; + if (!admin_user) macros_user = macros = mlast = NULL; /* Allow $recipients for this testing */ @@ -5140,6 +5155,8 @@ if (recipients_arg >= argc && !extract_recipients && !smtp_input) { if (version_printed) { + if (Ustrchr(config_main_filelist, ':')) + printf("Configuration file search path is %s\n", config_main_filelist); printf("Configuration file is %s\n", config_main_filename); return EXIT_SUCCESS; } @@ -5213,7 +5230,7 @@ already been done (which it will have been for inetd). This caters for the case when it is forced by -oMa. However, we must flag that it isn't a socket, so that the test for IP options is skipped for -bs input. */ -if (sender_host_address != NULL && sender_fullhost == NULL) +if (sender_host_address && !sender_fullhost) { host_build_sender_fullhost(); set_process_info("handling incoming connection from %s via -oMa",