X-Git-Url: https://git.exim.org/exim.git/blobdiff_plain/9af3c5495821f33fc0bdd09375ff246120b6ca99..fbf6767e15a0367d3f3a8462bc3a87d96bf7b71a:/src/src/exim.c diff --git a/src/src/exim.c b/src/src/exim.c index 198e81d89..83b5ef51f 100644 --- a/src/src/exim.c +++ b/src/src/exim.c @@ -140,14 +140,14 @@ regex_match_and_setup(const pcre *re, const uschar *subject, int options, int se int ovector[3*(EXPAND_MAXN+1)]; uschar * s = string_copy(subject); /* de-constifying */ int n = pcre_exec(re, NULL, CS s, Ustrlen(s), 0, - PCRE_EOPT | options, ovector, sizeof(ovector)/sizeof(int)); + PCRE_EOPT | options, ovector, nelem(ovector)); BOOL yield = n >= 0; if (n == 0) n = EXPAND_MAXN + 1; if (yield) { int nn; - expand_nmax = (setup < 0)? 0 : setup + 1; - for (nn = (setup < 0)? 0 : 2; nn < n*2; nn += 2) + expand_nmax = setup < 0 ? 0 : setup + 1; + for (nn = setup < 0 ? 0 : 2; nn < n*2; nn += 2) { expand_nstring[expand_nmax] = s + ovector[nn]; expand_nlength[expand_nmax++] = ovector[nn+1] - ovector[nn]; @@ -174,15 +174,22 @@ Returns: nothing void set_process_info(const char *format, ...) { -int len = sprintf(CS process_info, "%5d ", (int)getpid()); +gstring gs = { .size = PROCESS_INFO_SIZE - 2, .ptr = 0, .s = process_info }; +gstring * g; +int len; va_list ap; + +g = string_fmt_append(&gs, "%5d ", (int)getpid()); +len = g->ptr; va_start(ap, format); -if (!string_vformat(process_info + len, PROCESS_INFO_SIZE - len - 2, format, ap)) - Ustrcpy(process_info + len, "**** string overflowed buffer ****"); -len = Ustrlen(process_info); -process_info[len+0] = '\n'; -process_info[len+1] = '\0'; -process_info_len = len + 1; +if (!string_vformat(g, FALSE, format, ap)) + { + gs.ptr = len; + g = string_cat(&gs, US"**** string overflowed buffer ****"); + } +g = string_catn(g, US"\n", 1); +string_from_gstring(g); +process_info_len = g->ptr; DEBUG(D_process_info) debug_printf("set_process_info: %s", process_info); va_end(ap); } @@ -628,10 +635,10 @@ if (euid == root_uid || euid != uid || egid != gid || igflag) DEBUG(D_uid) { int group_count, save_errno; - gid_t group_list[NGROUPS_MAX]; + gid_t group_list[EXIM_GROUPLIST_SIZE]; debug_printf("changed uid/gid: %s\n uid=%ld gid=%ld pid=%ld\n", msg, (long int)geteuid(), (long int)getegid(), (long int)getpid()); - group_count = getgroups(NGROUPS_MAX, group_list); + group_count = getgroups(nelem(group_list), group_list); save_errno = errno; debug_printf(" auxiliary group list:"); if (group_count > 0) @@ -906,6 +913,9 @@ fprintf(fp, "Support for:"); #ifdef EXPERIMENTAL_REQUIRETLS fprintf(fp, " Experimental_REQUIRETLS"); #endif +#ifdef EXPERIMENTAL_PIPE_CONNECT + fprintf(fp, " Experimental_PIPE_CONNECT"); +#endif fprintf(fp, "\n"); fprintf(fp, "Lookups (built-in):"); @@ -1492,6 +1502,7 @@ int recipients_arg = argc; int sender_address_domain = 0; int test_retry_arg = -1; int test_rewrite_arg = -1; +gid_t original_egid; BOOL arg_queue_only = FALSE; BOOL bi_option = FALSE; BOOL checking = FALSE; @@ -1541,7 +1552,7 @@ struct passwd *pw; struct stat statbuf; pid_t passed_qr_pid = (pid_t)0; int passed_qr_pipe = -1; -gid_t group_list[NGROUPS_MAX]; +gid_t group_list[EXIM_GROUPLIST_SIZE]; /* For the -bI: flag */ enum commandline_info info_flag = CMDINFO_NONE; @@ -1818,6 +1829,7 @@ if ((namelen == 10 && Ustrcmp(argv[0], "newaliases") == 0) || normally be root, but in some esoteric environments it may not be. */ original_euid = geteuid(); +original_egid = getegid(); /* Get the real uid and gid. If the caller is root, force the effective uid/gid to be the same as the real ones. This makes a difference only if Exim is setuid @@ -2685,7 +2697,7 @@ for (i = 1; i < argc; i++) #ifdef SUPPORT_TLS /* -MCt: similar to -MCT below but the connection is still open - via a proxy proces which handles the TLS context and coding. + via a proxy process which handles the TLS context and coding. Require three arguments for the proxied local address and port, and the TLS cipher. */ @@ -3175,22 +3187,23 @@ for (i = 1; i < argc; i++) /* -q[f][f][l][G]: Run the queue, optionally forced, optionally local only, optionally named, optionally starting from a given message id. */ - if (*argrest == 0 && - (i + 1 >= argc || argv[i+1][0] == '-' || mac_ismsgid(argv[i+1]))) - { - queue_interval = 0; - if (i+1 < argc && mac_ismsgid(argv[i+1])) - start_queue_run_id = argv[++i]; - if (i+1 < argc && mac_ismsgid(argv[i+1])) - stop_queue_run_id = argv[++i]; - } + if (!(list_queue || count_queue)) + if (*argrest == 0 + && (i + 1 >= argc || argv[i+1][0] == '-' || mac_ismsgid(argv[i+1]))) + { + queue_interval = 0; + if (i+1 < argc && mac_ismsgid(argv[i+1])) + start_queue_run_id = argv[++i]; + if (i+1 < argc && mac_ismsgid(argv[i+1])) + stop_queue_run_id = argv[++i]; + } /* -q[f][f][l][G/]: Run the queue at regular intervals, optionally forced, optionally local only, optionally named. */ - else if ((queue_interval = readconf_readtime(*argrest ? argrest : argv[++i], - 0, FALSE)) <= 0) - exim_fail("exim: bad time value %s: abandoned\n", argv[i]); + else if ((queue_interval = readconf_readtime(*argrest ? argrest : argv[++i], + 0, FALSE)) <= 0) + exim_fail("exim: bad time value %s: abandoned\n", argv[i]); break; @@ -3532,7 +3545,7 @@ check on the additional groups for the admin user privilege - can't do that till after reading the config, which might specify the exim gid. Therefore, save the group list here first. */ -if ((group_count = getgroups(NGROUPS_MAX, group_list)) < 0) +if ((group_count = getgroups(nelem(group_list), group_list)) < 0) exim_fail("exim: getgroups() failed: %s\n", strerror(errno)); /* There is a fundamental difference in some BSD systems in the matter of @@ -3546,6 +3559,11 @@ over a single group - the current group, which is always the first group in the list. Calling setgroups() with zero groups on a "different" system results in an error return. The following code should cope with both types of system. + Unfortunately, recent MacOS, which should be a FreeBSD, "helpfully" succeeds + the "setgroups() with zero groups" - and changes the egid. + Thanks to that we had to stash the original_egid above, for use below + in the call to exim_setugid(). + However, if this process isn't running as root, setgroups() can't be used since you have to be root to run it, even if throwing away groups. Not being root here happens only in some unusual configurations. We just ignore the @@ -3605,7 +3623,7 @@ the real uid to the effective so that subsequent re-execs of Exim are done by a privileged user. */ else - exim_setugid(geteuid(), getegid(), FALSE, US"forcing real = effective"); + exim_setugid(geteuid(), original_egid, FALSE, US"forcing real = effective"); /* If testing a filter, open the file(s) now, before wasting time doing other setups and reading the message. */ @@ -3639,7 +3657,7 @@ if (f.running_in_test_harness) smtputf8_advertise_hosts = NULL; is a failure. It leaves the configuration file open so that the subsequent configuration data for delivery can be read if needed. -NOTE: immediatly after opening the configuration file we change the working +NOTE: immediately after opening the configuration file we change the working directory to "/"! Later we change to $spool_directory. We do it there, because during readconf_main() some expansion takes place already. */