X-Git-Url: https://vcs.fsf.org/?a=blobdiff_plain;f=src%2Fsrc%2Fexim.c;h=b1fff4ddf8bf5cdcba167903d4ad33727ec7c144;hb=a98e6acae2a0aa1ba884da4d6cfb4c107b053e25;hp=1ad76dea236dba748ef2f210c3230f1f05df0d80;hpb=5bde3efabfec675b323501cae5e3a99784afcc31;p=exim.git diff --git a/src/src/exim.c b/src/src/exim.c index 1ad76dea2..b1fff4ddf 100644 --- a/src/src/exim.c +++ b/src/src/exim.c @@ -174,10 +174,8 @@ Returns: nothing void set_process_info(const char *format, ...) { -int len; +int len = sprintf(CS process_info, "%5d ", (int)getpid()); va_list ap; -sprintf(CS process_info, "%5d ", (int)getpid()); -len = Ustrlen(process_info); va_start(ap, format); if (!string_vformat(process_info + len, PROCESS_INFO_SIZE - len - 2, format, ap)) Ustrcpy(process_info + len, "**** string overflowed buffer ****"); @@ -845,6 +843,9 @@ fprintf(f, "Support for:"); #ifdef EXPERIMENTAL_LMDB fprintf(f, " Experimental_LMDB"); #endif +#ifdef EXPERIMENTAL_QUEUEFILE + fprintf(f, " Experimental_QUEUEFILE"); +#endif #ifdef EXPERIMENTAL_SPF fprintf(f, " Experimental_SPF"); #endif @@ -998,6 +999,9 @@ fprintf(f, "Transports:"); #ifdef TRANSPORT_PIPE fprintf(f, " pipe"); #endif +#ifdef EXPERIMENTAL_QUEUEFILE + fprintf(f, " queuefile"); +#endif #ifdef TRANSPORT_SMTP fprintf(f, " smtp"); #endif @@ -1012,6 +1016,8 @@ if (fixed_never_users[0] > 0) fprintf(f, "%d\n", (unsigned int)fixed_never_users[i]); } +fprintf(f, "Configure owner: %d:%d\n", config_uid, config_gid); + fprintf(f, "Size of off_t: " SIZE_T_FMT "\n", sizeof(off_t)); /* Everything else is details which are only worth reporting when debugging. @@ -1349,12 +1355,12 @@ exit(EXIT_FAILURE); /* Typically, Exim will drop privileges if macros are supplied. In some cases, we want to not do so. -Arguments: none (macros is a global) +Arguments: opt_D_used - true if the commandline had a "-D" option Returns: true if trusted, false otherwise */ static BOOL -macros_trusted(void) +macros_trusted(BOOL opt_D_used) { #ifdef WHITELIST_D_MACROS macro_item *m; @@ -1364,7 +1370,7 @@ size_t len; BOOL prev_char_item, found; #endif -if (macros == NULL) +if (!opt_D_used) return TRUE; #ifndef WHITELIST_D_MACROS return FALSE; @@ -1421,8 +1427,9 @@ for (p = whitelisted, i = 0; (p != end) && (i < white_count); ++p) } whites[i] = NULL; -/* The list of macros should be very short. Accept the N*M complexity. */ -for (m = macros; m != NULL; m = m->next) +/* The list of commandline macros should be very short. +Accept the N*M complexity. */ +for (m = macros; m; m = m->next) if (m->command_line) { found = FALSE; for (w = whites; *w; ++w) @@ -1512,6 +1519,7 @@ BOOL list_config = FALSE; BOOL local_queue_only; BOOL more = TRUE; BOOL one_msg_action = FALSE; +BOOL opt_D_used = FALSE; BOOL queue_only_set = FALSE; BOOL receiving_message = TRUE; BOOL sender_ident_set = FALSE; @@ -1653,8 +1661,7 @@ os_non_restarting_signal(SIGALRM, sigalrm_handler); /* Ensure we have a buffer for constructing log entries. Use malloc directly, because store_malloc writes a log entry on failure. */ -log_buffer = (uschar *)malloc(LOG_BUFFER_SIZE); -if (log_buffer == NULL) +if (!(log_buffer = US malloc(LOG_BUFFER_SIZE))) { fprintf(stderr, "exim: failed to get store for log buffer\n"); exit(EXIT_FAILURE); @@ -2412,11 +2419,11 @@ for (i = 1; i < argc; i++) #else { int ptr = 0; - macro_item *mlast = NULL; macro_item *m; uschar name[24]; uschar *s = argrest; + opt_D_used = TRUE; while (isspace(*s)) s++; if (*s < 'A' || *s > 'Z') @@ -2440,22 +2447,14 @@ for (i = 1; i < argc; i++) while (isspace(*s)) s++; } - for (m = macros; m != NULL; m = m->next) - { + for (m = macros; m; m = m->next) if (Ustrcmp(m->name, name) == 0) { fprintf(stderr, "exim: duplicated -D in command line\n"); exit(EXIT_FAILURE); } - mlast = m; - } - m = store_get(sizeof(macro_item) + Ustrlen(name)); - m->next = NULL; - m->command_line = TRUE; - if (mlast == NULL) macros = m; else mlast->next = m; - Ustrcpy(m->name, name); - m->replacement = string_copy(s); + m = macro_create(name, s, TRUE, FALSE); if (clmacro_count >= MAX_CLMACROS) { @@ -3686,7 +3685,7 @@ configuration file changes and macro definitions haven't happened. */ if (( /* EITHER */ (!trusted_config || /* Config changed, or */ - !macros_trusted()) && /* impermissible macros and */ + !macros_trusted(opt_D_used)) && /* impermissible macros and */ real_uid != root_uid && /* Not root, and */ !running_in_test_harness /* Not fudged */ ) || /* OR */ @@ -3938,7 +3937,6 @@ if (Ustrlen(syslog_processname) > 32) "syslog_processname is longer than 32 chars: aborting"); if (log_oneline) - { if (admin_user) { log_write(0, LOG_MAIN, "%s", log_oneline); @@ -3946,7 +3944,6 @@ if (log_oneline) } else return EXIT_FAILURE; - } /* In some operating systems, the environment variable TMPDIR controls where temporary files are created; Exim doesn't use these (apart from when delivering @@ -3960,17 +3957,14 @@ EXIM_TMPDIR by the build scripts. #ifdef EXIM_TMPDIR { uschar **p; - if (environ) for (p = USS environ; *p != NULL; p++) - { - if (Ustrncmp(*p, "TMPDIR=", 7) == 0 && - Ustrcmp(*p+7, EXIM_TMPDIR) != 0) + if (environ) for (p = USS environ; *p; p++) + if (Ustrncmp(*p, "TMPDIR=", 7) == 0 && Ustrcmp(*p+7, EXIM_TMPDIR) != 0) { - uschar *newp = malloc(Ustrlen(EXIM_TMPDIR) + 8); + uschar * newp = store_malloc(Ustrlen(EXIM_TMPDIR) + 8); sprintf(CS newp, "TMPDIR=%s", EXIM_TMPDIR); *p = newp; DEBUG(D_any) debug_printf("reset TMPDIR=%s in environment\n", EXIM_TMPDIR); } - } } #endif @@ -3984,33 +3978,28 @@ about this earlier - but hopefully nothing will normally be logged earlier than this. We have to make a new environment if TZ is wrong, but don't bother if timestamps_utc is set, because then all times are in UTC anyway. */ -if (timezone_string != NULL && strcmpic(timezone_string, US"UTC") == 0) - { +if (timezone_string && strcmpic(timezone_string, US"UTC") == 0) timestamps_utc = TRUE; - } else { uschar *envtz = US getenv("TZ"); - if ((envtz == NULL && timezone_string != NULL) || - (envtz != NULL && - (timezone_string == NULL || - Ustrcmp(timezone_string, envtz) != 0))) + if (envtz + ? !timezone_string || Ustrcmp(timezone_string, envtz) != 0 + : timezone_string != NULL + ) { uschar **p = USS environ; uschar **new; uschar **newp; int count = 0; - if (environ) while (*p++ != NULL) count++; - if (envtz == NULL) count++; - newp = new = malloc(sizeof(uschar *) * (count + 1)); - if (environ) for (p = USS environ; *p != NULL; p++) - { - if (Ustrncmp(*p, "TZ=", 3) == 0) continue; - *newp++ = *p; - } - if (timezone_string != NULL) + if (environ) while (*p++) count++; + if (!envtz) count++; + newp = new = store_malloc(sizeof(uschar *) * (count + 1)); + if (environ) for (p = USS environ; *p; p++) + if (Ustrncmp(*p, "TZ=", 3) != 0) *newp++ = *p; + if (timezone_string) { - *newp = malloc(Ustrlen(timezone_string) + 4); + *newp = store_malloc(Ustrlen(timezone_string) + 4); sprintf(CS *newp++, "TZ=%s", timezone_string); } *newp = NULL; @@ -4042,16 +4031,15 @@ Exim user", but it hasn't, because either the -D option set macros, or the root for -C or -D, the caller must either be root or be invoking a trusted configuration file (when deliver_drop_privilege is false). */ -if (removed_privilege && (!trusted_config || macros != NULL) && - real_uid == exim_uid) - { +if ( removed_privilege + && (!trusted_config || opt_D_used) + && real_uid == exim_uid) if (deliver_drop_privilege) really_exim = TRUE; /* let logging work normally */ else log_write(0, LOG_MAIN|LOG_PANIC, "exim user lost privilege for using %s option", trusted_config? "-D" : "-C"); - } /* Start up Perl interpreter if Perl support is configured and there is a perl_startup option, and the configuration or the command line specifies @@ -5549,7 +5537,7 @@ while (more) ignored; rejecting here would just add complication, and it can just as well be done later. Allow $recipients to be visible in the ACL. */ - if (acl_not_smtp_start != NULL) + if (acl_not_smtp_start) { uschar *user_msg, *log_msg; enable_dollar_recipients = TRUE; @@ -5558,6 +5546,20 @@ while (more) enable_dollar_recipients = FALSE; } + /* Pause for a while waiting for input. If none received in that time, + close the logfile, if we had one open; then if we wait for a long-running + datasource (months, in one use-case) log rotation will not leave us holding + the file copy. */ + + if (!receive_timeout) + { + struct timeval t = { 30*60, 0 }; /* 30 minutess */ + fd_set r; + + FD_ZERO(&r); FD_SET(0, &r); + if (select(1, &r, NULL, NULL, &t) == 0) mainlog_close(); + } + /* Read the data for the message. If filter_test is not FTEST_NONE, this will just read the headers for the message, and not write anything onto the spool. */