Commit | Line | Data |
---|---|---|
929ba01c | 1 | /* $Cambridge: exim/src/src/exim.c,v 1.34 2006/02/21 16:24:19 ph10 Exp $ */ |
059ec3d9 PH |
2 | |
3 | /************************************************* | |
4 | * Exim - an Internet mail transport agent * | |
5 | *************************************************/ | |
6 | ||
d7d7b7b9 | 7 | /* Copyright (c) University of Cambridge 1995 - 2006 */ |
059ec3d9 PH |
8 | /* See the file NOTICE for conditions of use and distribution. */ |
9 | ||
10 | ||
11 | /* The main function: entry point, initialization, and high-level control. | |
12 | Also a few functions that don't naturally fit elsewhere. */ | |
13 | ||
14 | ||
15 | #include "exim.h" | |
16 | ||
17 | ||
18 | ||
19 | /************************************************* | |
20 | * Function interface to store functions * | |
21 | *************************************************/ | |
22 | ||
23 | /* We need some real functions to pass to the PCRE regular expression library | |
24 | for store allocation via Exim's store manager. The normal calls are actually | |
25 | macros that pass over location information to make tracing easier. These | |
26 | functions just interface to the standard macro calls. A good compiler will | |
27 | optimize out the tail recursion and so not make them too expensive. There | |
28 | are two sets of functions; one for use when we want to retain the compiled | |
29 | regular expression for a long time; the other for short-term use. */ | |
30 | ||
31 | static void * | |
32 | function_store_get(size_t size) | |
33 | { | |
34 | return store_get((int)size); | |
35 | } | |
36 | ||
37 | static void | |
38 | function_dummy_free(void *block) { block = block; } | |
39 | ||
40 | static void * | |
41 | function_store_malloc(size_t size) | |
42 | { | |
43 | return store_malloc((int)size); | |
44 | } | |
45 | ||
46 | static void | |
47 | function_store_free(void *block) | |
48 | { | |
49 | store_free(block); | |
50 | } | |
51 | ||
52 | ||
53 | ||
54 | ||
55 | /************************************************* | |
56 | * Compile regular expression and panic on fail * | |
57 | *************************************************/ | |
58 | ||
59 | /* This function is called when failure to compile a regular expression leads | |
60 | to a panic exit. In other cases, pcre_compile() is called directly. In many | |
61 | cases where this function is used, the results of the compilation are to be | |
62 | placed in long-lived store, so we temporarily reset the store management | |
63 | functions that PCRE uses if the use_malloc flag is set. | |
64 | ||
65 | Argument: | |
66 | pattern the pattern to compile | |
67 | caseless TRUE if caseless matching is required | |
68 | use_malloc TRUE if compile into malloc store | |
69 | ||
70 | Returns: pointer to the compiled pattern | |
71 | */ | |
72 | ||
73 | const pcre * | |
74 | regex_must_compile(uschar *pattern, BOOL caseless, BOOL use_malloc) | |
75 | { | |
76 | int offset; | |
77 | int options = PCRE_COPT; | |
78 | const pcre *yield; | |
79 | const uschar *error; | |
80 | if (use_malloc) | |
81 | { | |
82 | pcre_malloc = function_store_malloc; | |
83 | pcre_free = function_store_free; | |
84 | } | |
85 | if (caseless) options |= PCRE_CASELESS; | |
86 | yield = pcre_compile(CS pattern, options, (const char **)&error, &offset, NULL); | |
87 | pcre_malloc = function_store_get; | |
88 | pcre_free = function_dummy_free; | |
89 | if (yield == NULL) | |
90 | log_write(0, LOG_MAIN|LOG_PANIC_DIE, "regular expression error: " | |
91 | "%s at offset %d while compiling %s", error, offset, pattern); | |
92 | return yield; | |
93 | } | |
94 | ||
95 | ||
96 | ||
97 | ||
98 | /************************************************* | |
99 | * Execute regular expression and set strings * | |
100 | *************************************************/ | |
101 | ||
102 | /* This function runs a regular expression match, and sets up the pointers to | |
103 | the matched substrings. | |
104 | ||
105 | Arguments: | |
106 | re the compiled expression | |
107 | subject the subject string | |
108 | options additional PCRE options | |
109 | setup if < 0 do full setup | |
110 | if >= 0 setup from setup+1 onwards, | |
111 | excluding the full matched string | |
112 | ||
113 | Returns: TRUE or FALSE | |
114 | */ | |
115 | ||
116 | BOOL | |
117 | regex_match_and_setup(const pcre *re, uschar *subject, int options, int setup) | |
118 | { | |
119 | int ovector[3*(EXPAND_MAXN+1)]; | |
120 | int n = pcre_exec(re, NULL, CS subject, Ustrlen(subject), 0, | |
121 | PCRE_EOPT | options, ovector, sizeof(ovector)/sizeof(int)); | |
122 | BOOL yield = n >= 0; | |
123 | if (n == 0) n = EXPAND_MAXN + 1; | |
124 | if (yield) | |
125 | { | |
126 | int nn; | |
127 | expand_nmax = (setup < 0)? 0 : setup + 1; | |
128 | for (nn = (setup < 0)? 0 : 2; nn < n*2; nn += 2) | |
129 | { | |
130 | expand_nstring[expand_nmax] = subject + ovector[nn]; | |
131 | expand_nlength[expand_nmax++] = ovector[nn+1] - ovector[nn]; | |
132 | } | |
133 | expand_nmax--; | |
134 | } | |
135 | return yield; | |
136 | } | |
137 | ||
138 | ||
139 | ||
140 | ||
141 | /************************************************* | |
142 | * Handler for SIGUSR1 * | |
143 | *************************************************/ | |
144 | ||
145 | /* SIGUSR1 causes any exim process to write to the process log details of | |
146 | what it is currently doing. It will only be used if the OS is capable of | |
147 | setting up a handler that causes automatic restarting of any system call | |
148 | that is in progress at the time. | |
149 | ||
150 | Argument: the signal number (SIGUSR1) | |
151 | Returns: nothing | |
152 | */ | |
153 | ||
154 | static void | |
155 | usr1_handler(int sig) | |
156 | { | |
157 | sig = sig; /* Keep picky compilers happy */ | |
158 | log_write(0, LOG_PROCESS, "%s", process_info); | |
159 | log_close_all(); | |
160 | os_restarting_signal(SIGUSR1, usr1_handler); | |
161 | } | |
162 | ||
163 | ||
164 | ||
165 | /************************************************* | |
166 | * Timeout handler * | |
167 | *************************************************/ | |
168 | ||
169 | /* This handler is enabled most of the time that Exim is running. The handler | |
170 | doesn't actually get used unless alarm() has been called to set a timer, to | |
171 | place a time limit on a system call of some kind. When the handler is run, it | |
172 | re-enables itself. | |
173 | ||
174 | There are some other SIGALRM handlers that are used in special cases when more | |
175 | than just a flag setting is required; for example, when reading a message's | |
176 | input. These are normally set up in the code module that uses them, and the | |
177 | SIGALRM handler is reset to this one afterwards. | |
178 | ||
179 | Argument: the signal value (SIGALRM) | |
180 | Returns: nothing | |
181 | */ | |
182 | ||
183 | void | |
184 | sigalrm_handler(int sig) | |
185 | { | |
186 | sig = sig; /* Keep picky compilers happy */ | |
187 | sigalrm_seen = TRUE; | |
188 | os_non_restarting_signal(SIGALRM, sigalrm_handler); | |
189 | } | |
190 | ||
191 | ||
192 | ||
193 | /************************************************* | |
194 | * Sleep for a fractional time interval * | |
195 | *************************************************/ | |
196 | ||
197 | /* This function is called by millisleep() and exim_wait_tick() to wait for a | |
198 | period of time that may include a fraction of a second. The coding is somewhat | |
eb2c0248 PH |
199 | tedious. We do not expect setitimer() ever to fail, but if it does, the process |
200 | will wait for ever, so we panic in this instance. (There was a case of this | |
201 | when a bug in a function that calls milliwait() caused it to pass invalid data. | |
7086e875 | 202 | That's when I added the check. :-) |
059ec3d9 PH |
203 | |
204 | Argument: an itimerval structure containing the interval | |
205 | Returns: nothing | |
206 | */ | |
207 | ||
208 | static void | |
209 | milliwait(struct itimerval *itval) | |
210 | { | |
211 | sigset_t sigmask; | |
212 | sigset_t old_sigmask; | |
213 | (void)sigemptyset(&sigmask); /* Empty mask */ | |
214 | (void)sigaddset(&sigmask, SIGALRM); /* Add SIGALRM */ | |
215 | (void)sigprocmask(SIG_BLOCK, &sigmask, &old_sigmask); /* Block SIGALRM */ | |
7086e875 | 216 | if (setitimer(ITIMER_REAL, itval, NULL) < 0) /* Start timer */ |
eb2c0248 PH |
217 | log_write(0, LOG_MAIN|LOG_PANIC_DIE, |
218 | "setitimer() failed: %s", strerror(errno)); | |
059ec3d9 PH |
219 | (void)sigfillset(&sigmask); /* All signals */ |
220 | (void)sigdelset(&sigmask, SIGALRM); /* Remove SIGALRM */ | |
221 | (void)sigsuspend(&sigmask); /* Until SIGALRM */ | |
222 | (void)sigprocmask(SIG_SETMASK, &old_sigmask, NULL); /* Restore mask */ | |
223 | } | |
224 | ||
225 | ||
226 | ||
227 | ||
228 | /************************************************* | |
229 | * Millisecond sleep function * | |
230 | *************************************************/ | |
231 | ||
232 | /* The basic sleep() function has a granularity of 1 second, which is too rough | |
233 | in some cases - for example, when using an increasing delay to slow down | |
234 | spammers. | |
235 | ||
236 | Argument: number of millseconds | |
237 | Returns: nothing | |
238 | */ | |
239 | ||
240 | void | |
241 | millisleep(int msec) | |
242 | { | |
243 | struct itimerval itval; | |
244 | itval.it_interval.tv_sec = 0; | |
245 | itval.it_interval.tv_usec = 0; | |
246 | itval.it_value.tv_sec = msec/1000; | |
247 | itval.it_value.tv_usec = (msec % 1000) * 1000; | |
248 | milliwait(&itval); | |
249 | } | |
250 | ||
251 | ||
252 | ||
253 | /************************************************* | |
254 | * Compare microsecond times * | |
255 | *************************************************/ | |
256 | ||
257 | /* | |
258 | Arguments: | |
259 | tv1 the first time | |
260 | tv2 the second time | |
261 | ||
262 | Returns: -1, 0, or +1 | |
263 | */ | |
264 | ||
265 | int | |
266 | exim_tvcmp(struct timeval *t1, struct timeval *t2) | |
267 | { | |
268 | if (t1->tv_sec > t2->tv_sec) return +1; | |
269 | if (t1->tv_sec < t2->tv_sec) return -1; | |
270 | if (t1->tv_usec > t2->tv_usec) return +1; | |
271 | if (t1->tv_usec < t2->tv_usec) return -1; | |
272 | return 0; | |
273 | } | |
274 | ||
275 | ||
276 | ||
277 | ||
278 | /************************************************* | |
279 | * Clock tick wait function * | |
280 | *************************************************/ | |
281 | ||
282 | /* Exim uses a time + a pid to generate a unique identifier in two places: its | |
283 | message IDs, and in file names for maildir deliveries. Because some OS now | |
284 | re-use pids within the same second, sub-second times are now being used. | |
285 | However, for absolute certaintly, we must ensure the clock has ticked before | |
286 | allowing the relevant process to complete. At the time of implementation of | |
287 | this code (February 2003), the speed of processors is such that the clock will | |
288 | invariably have ticked already by the time a process has done its job. This | |
289 | function prepares for the time when things are faster - and it also copes with | |
290 | clocks that go backwards. | |
291 | ||
292 | Arguments: | |
293 | then_tv A timeval which was used to create uniqueness; its usec field | |
294 | has been rounded down to the value of the resolution. | |
295 | We want to be sure the current time is greater than this. | |
296 | resolution The resolution that was used to divide the microseconds | |
297 | (1 for maildir, larger for message ids) | |
298 | ||
299 | Returns: nothing | |
300 | */ | |
301 | ||
302 | void | |
303 | exim_wait_tick(struct timeval *then_tv, int resolution) | |
304 | { | |
305 | struct timeval now_tv; | |
306 | long int now_true_usec; | |
307 | ||
308 | (void)gettimeofday(&now_tv, NULL); | |
309 | now_true_usec = now_tv.tv_usec; | |
310 | now_tv.tv_usec = (now_true_usec/resolution) * resolution; | |
311 | ||
312 | if (exim_tvcmp(&now_tv, then_tv) <= 0) | |
313 | { | |
314 | struct itimerval itval; | |
315 | itval.it_interval.tv_sec = 0; | |
316 | itval.it_interval.tv_usec = 0; | |
317 | itval.it_value.tv_sec = then_tv->tv_sec - now_tv.tv_sec; | |
318 | itval.it_value.tv_usec = then_tv->tv_usec + resolution - now_true_usec; | |
319 | ||
320 | /* We know that, overall, "now" is less than or equal to "then". Therefore, a | |
321 | negative value for the microseconds is possible only in the case when "now" | |
322 | is more than a second less than "then". That means that itval.it_value.tv_sec | |
323 | is greater than zero. The following correction is therefore safe. */ | |
324 | ||
325 | if (itval.it_value.tv_usec < 0) | |
326 | { | |
327 | itval.it_value.tv_usec += 1000000; | |
328 | itval.it_value.tv_sec -= 1; | |
329 | } | |
330 | ||
331 | DEBUG(D_transport|D_receive) | |
332 | { | |
333 | if (!running_in_test_harness) | |
334 | { | |
335 | debug_printf("tick check: %lu.%06lu %lu.%06lu\n", | |
336 | then_tv->tv_sec, then_tv->tv_usec, now_tv.tv_sec, now_tv.tv_usec); | |
337 | debug_printf("waiting %lu.%06lu\n", itval.it_value.tv_sec, | |
338 | itval.it_value.tv_usec); | |
339 | } | |
340 | } | |
341 | ||
342 | milliwait(&itval); | |
343 | } | |
344 | } | |
345 | ||
346 | ||
347 | ||
348 | ||
349 | /************************************************* | |
350 | * Set up processing details * | |
351 | *************************************************/ | |
352 | ||
353 | /* Save a text string for dumping when SIGUSR1 is received. | |
354 | Do checks for overruns. | |
355 | ||
356 | Arguments: format and arguments, as for printf() | |
357 | Returns: nothing | |
358 | */ | |
359 | ||
360 | void | |
361 | set_process_info(char *format, ...) | |
362 | { | |
363 | int len; | |
364 | va_list ap; | |
365 | sprintf(CS process_info, "%5d ", (int)getpid()); | |
366 | len = Ustrlen(process_info); | |
367 | va_start(ap, format); | |
368 | if (!string_vformat(process_info + len, PROCESS_INFO_SIZE - len, format, ap)) | |
369 | Ustrcpy(process_info + len, "**** string overflowed buffer ****"); | |
370 | DEBUG(D_process_info) debug_printf("set_process_info: %s\n", process_info); | |
371 | va_end(ap); | |
372 | } | |
373 | ||
374 | ||
375 | ||
376 | ||
377 | ||
378 | /************************************************* | |
379 | * Ensure stdin, stdout, and stderr exist * | |
380 | *************************************************/ | |
381 | ||
382 | /* Some operating systems grumble if an exec() happens without a standard | |
383 | input, output, and error (fds 0, 1, 2) being defined. The worry is that some | |
384 | file will be opened and will use these fd values, and then some other bit of | |
385 | code will assume, for example, that it can write error messages to stderr. | |
386 | This function ensures that fds 0, 1, and 2 are open if they do not already | |
387 | exist, by connecting them to /dev/null. | |
388 | ||
389 | This function is also used to ensure that std{in,out,err} exist at all times, | |
390 | so that if any library that Exim calls tries to use them, it doesn't crash. | |
391 | ||
392 | Arguments: None | |
393 | Returns: Nothing | |
394 | */ | |
395 | ||
396 | void | |
397 | exim_nullstd(void) | |
398 | { | |
399 | int i; | |
400 | int devnull = -1; | |
401 | struct stat statbuf; | |
402 | for (i = 0; i <= 2; i++) | |
403 | { | |
404 | if (fstat(i, &statbuf) < 0 && errno == EBADF) | |
405 | { | |
406 | if (devnull < 0) devnull = open("/dev/null", O_RDWR); | |
407 | if (devnull < 0) log_write(0, LOG_MAIN|LOG_PANIC_DIE, "%s", | |
408 | string_open_failed(errno, "/dev/null")); | |
1fe64dcc | 409 | if (devnull != i) (void)dup2(devnull, i); |
059ec3d9 PH |
410 | } |
411 | } | |
1fe64dcc | 412 | if (devnull > 2) (void)close(devnull); |
059ec3d9 PH |
413 | } |
414 | ||
415 | ||
416 | ||
417 | ||
418 | /************************************************* | |
419 | * Close unwanted file descriptors for delivery * | |
420 | *************************************************/ | |
421 | ||
422 | /* This function is called from a new process that has been forked to deliver | |
423 | an incoming message, either directly, or using exec. | |
424 | ||
425 | We want any smtp input streams to be closed in this new process. However, it | |
426 | has been observed that using fclose() here causes trouble. When reading in -bS | |
427 | input, duplicate copies of messages have been seen. The files will be sharing a | |
428 | file pointer with the parent process, and it seems that fclose() (at least on | |
429 | some systems - I saw this on Solaris 2.5.1) messes with that file pointer, at | |
430 | least sometimes. Hence we go for closing the underlying file descriptors. | |
431 | ||
432 | If TLS is active, we want to shut down the TLS library, but without molesting | |
433 | the parent's SSL connection. | |
434 | ||
435 | For delivery of a non-SMTP message, we want to close stdin and stdout (and | |
436 | stderr unless debugging) because the calling process might have set them up as | |
437 | pipes and be waiting for them to close before it waits for the submission | |
438 | process to terminate. If they aren't closed, they hold up the calling process | |
439 | until the initial delivery process finishes, which is not what we want. | |
440 | ||
441 | Exception: We do want it for synchronous delivery! | |
442 | ||
443 | And notwithstanding all the above, if D_resolver is set, implying resolver | |
444 | debugging, leave stdout open, because that's where the resolver writes its | |
445 | debugging output. | |
446 | ||
447 | When we close stderr (which implies we've also closed stdout), we also get rid | |
448 | of any controlling terminal. | |
449 | ||
450 | Arguments: None | |
451 | Returns: Nothing | |
452 | */ | |
453 | ||
454 | static void | |
455 | close_unwanted(void) | |
456 | { | |
457 | if (smtp_input) | |
458 | { | |
459 | #ifdef SUPPORT_TLS | |
460 | tls_close(FALSE); /* Shut down the TLS library */ | |
461 | #endif | |
1fe64dcc PH |
462 | (void)close(fileno(smtp_in)); |
463 | (void)close(fileno(smtp_out)); | |
059ec3d9 PH |
464 | smtp_in = NULL; |
465 | } | |
466 | else | |
467 | { | |
1fe64dcc PH |
468 | (void)close(0); /* stdin */ |
469 | if ((debug_selector & D_resolver) == 0) (void)close(1); /* stdout */ | |
470 | if (debug_selector == 0) /* stderr */ | |
059ec3d9 PH |
471 | { |
472 | if (!synchronous_delivery) | |
473 | { | |
1fe64dcc | 474 | (void)close(2); |
059ec3d9 PH |
475 | log_stderr = NULL; |
476 | } | |
477 | (void)setsid(); | |
478 | } | |
479 | } | |
480 | } | |
481 | ||
482 | ||
483 | ||
484 | ||
485 | /************************************************* | |
486 | * Set uid and gid * | |
487 | *************************************************/ | |
488 | ||
489 | /* This function sets a new uid and gid permanently, optionally calling | |
490 | initgroups() to set auxiliary groups. There are some special cases when running | |
491 | Exim in unprivileged modes. In these situations the effective uid will not be | |
492 | root; if we already have the right effective uid/gid, and don't need to | |
493 | initialize any groups, leave things as they are. | |
494 | ||
495 | Arguments: | |
496 | uid the uid | |
497 | gid the gid | |
498 | igflag TRUE if initgroups() wanted | |
499 | msg text to use in debugging output and failure log | |
500 | ||
501 | Returns: nothing; bombs out on failure | |
502 | */ | |
503 | ||
504 | void | |
505 | exim_setugid(uid_t uid, gid_t gid, BOOL igflag, uschar *msg) | |
506 | { | |
507 | uid_t euid = geteuid(); | |
508 | gid_t egid = getegid(); | |
509 | ||
510 | if (euid == root_uid || euid != uid || egid != gid || igflag) | |
511 | { | |
512 | /* At least one OS returns +1 for initgroups failure, so just check for | |
513 | non-zero. */ | |
514 | ||
515 | if (igflag) | |
516 | { | |
517 | struct passwd *pw = getpwuid(uid); | |
518 | if (pw != NULL) | |
519 | { | |
520 | if (initgroups(pw->pw_name, gid) != 0) | |
521 | log_write(0,LOG_MAIN|LOG_PANIC_DIE,"initgroups failed for uid=%ld: %s", | |
522 | (long int)uid, strerror(errno)); | |
523 | } | |
524 | else log_write(0, LOG_MAIN|LOG_PANIC_DIE, "cannot run initgroups(): " | |
525 | "no passwd entry for uid=%ld", (long int)uid); | |
526 | } | |
527 | ||
528 | if (setgid(gid) < 0 || setuid(uid) < 0) | |
529 | { | |
530 | log_write(0, LOG_MAIN|LOG_PANIC_DIE, "unable to set gid=%ld or uid=%ld " | |
531 | "(euid=%ld): %s", (long int)gid, (long int)uid, (long int)euid, msg); | |
532 | } | |
533 | } | |
534 | ||
535 | /* Debugging output included uid/gid and all groups */ | |
536 | ||
537 | DEBUG(D_uid) | |
538 | { | |
539 | int group_count; | |
540 | gid_t group_list[NGROUPS_MAX]; | |
541 | debug_printf("changed uid/gid: %s\n uid=%ld gid=%ld pid=%ld\n", msg, | |
542 | (long int)geteuid(), (long int)getegid(), (long int)getpid()); | |
543 | group_count = getgroups(NGROUPS_MAX, group_list); | |
544 | debug_printf(" auxiliary group list:"); | |
545 | if (group_count > 0) | |
546 | { | |
547 | int i; | |
548 | for (i = 0; i < group_count; i++) debug_printf(" %d", (int)group_list[i]); | |
549 | } | |
550 | else debug_printf(" <none>"); | |
551 | debug_printf("\n"); | |
552 | } | |
553 | } | |
554 | ||
555 | ||
556 | ||
557 | ||
558 | /************************************************* | |
559 | * Exit point * | |
560 | *************************************************/ | |
561 | ||
562 | /* Exim exits via this function so that it always clears up any open | |
563 | databases. | |
564 | ||
565 | Arguments: | |
566 | rc return code | |
567 | ||
568 | Returns: does not return | |
569 | */ | |
570 | ||
571 | void | |
572 | exim_exit(int rc) | |
573 | { | |
574 | search_tidyup(); | |
575 | DEBUG(D_any) | |
576 | debug_printf(">>>>>>>>>>>>>>>> Exim pid=%d terminating with rc=%d " | |
577 | ">>>>>>>>>>>>>>>>\n", (int)getpid(), rc); | |
578 | exit(rc); | |
579 | } | |
580 | ||
581 | ||
582 | ||
583 | ||
584 | /************************************************* | |
585 | * Extract port from host address * | |
586 | *************************************************/ | |
587 | ||
588 | /* Called to extract the port from the values given to -oMa and -oMi. | |
b90c388a PH |
589 | It also checks the syntax of the address, and terminates it before the |
590 | port data when a port is extracted. | |
059ec3d9 PH |
591 | |
592 | Argument: | |
593 | address the address, with possible port on the end | |
594 | ||
595 | Returns: the port, or zero if there isn't one | |
596 | bombs out on a syntax error | |
597 | */ | |
598 | ||
599 | static int | |
600 | check_port(uschar *address) | |
601 | { | |
7cd1141b | 602 | int port = host_address_extract_port(address); |
8e669ac1 | 603 | if (string_is_ip_address(address, NULL) == 0) |
059ec3d9 PH |
604 | { |
605 | fprintf(stderr, "exim abandoned: \"%s\" is not an IP address\n", address); | |
606 | exit(EXIT_FAILURE); | |
607 | } | |
608 | return port; | |
609 | } | |
610 | ||
611 | ||
612 | ||
613 | /************************************************* | |
614 | * Test/verify an address * | |
615 | *************************************************/ | |
616 | ||
617 | /* This function is called by the -bv and -bt code. It extracts a working | |
618 | address from a full RFC 822 address. This isn't really necessary per se, but it | |
619 | has the effect of collapsing source routes. | |
620 | ||
621 | Arguments: | |
622 | s the address string | |
623 | flags flag bits for verify_address() | |
624 | exit_value to be set for failures | |
625 | ||
a5a28604 | 626 | Returns: nothing |
059ec3d9 PH |
627 | */ |
628 | ||
629 | static void | |
630 | test_address(uschar *s, int flags, int *exit_value) | |
631 | { | |
632 | int start, end, domain; | |
633 | uschar *parse_error = NULL; | |
634 | uschar *address = parse_extract_address(s, &parse_error, &start, &end, &domain, | |
635 | FALSE); | |
636 | if (address == NULL) | |
637 | { | |
638 | fprintf(stdout, "syntax error: %s\n", parse_error); | |
639 | *exit_value = 2; | |
640 | } | |
641 | else | |
642 | { | |
643 | int rc = verify_address(deliver_make_addr(address,TRUE), stdout, flags, -1, | |
4deaf07d | 644 | -1, -1, NULL, NULL, NULL); |
059ec3d9 PH |
645 | if (rc == FAIL) *exit_value = 2; |
646 | else if (rc == DEFER && *exit_value == 0) *exit_value = 1; | |
647 | } | |
648 | } | |
649 | ||
650 | ||
651 | ||
652 | /************************************************* | |
653 | * Decode bit settings for log/debug * | |
654 | *************************************************/ | |
655 | ||
656 | /* This function decodes a string containing bit settings in the form of +name | |
657 | and/or -name sequences, and sets/unsets bits in a bit string accordingly. It | |
658 | also recognizes a numeric setting of the form =<number>, but this is not | |
659 | intended for user use. It's an easy way for Exim to pass the debug settings | |
660 | when it is re-exec'ed. | |
661 | ||
662 | The log options are held in two unsigned ints (because there became too many | |
663 | for one). The top bit in the table means "put in 2nd selector". This does not | |
664 | yet apply to debug options, so the "=" facility sets only the first selector. | |
665 | ||
1fe64dcc PH |
666 | The "all" selector, which must be equal to 0xffffffff, is recognized specially. |
667 | It sets all the bits in both selectors. However, there is a facility for then | |
668 | unsetting certain bits, because we want to turn off "memory" in the debug case. | |
669 | ||
059ec3d9 PH |
670 | A bad value for a debug setting is treated as an unknown option - error message |
671 | to stderr and die. For log settings, which come from the configuration file, | |
672 | we write to the log on the way out... | |
673 | ||
674 | Arguments: | |
675 | selector1 address of the first bit string | |
676 | selector2 address of the second bit string, or NULL | |
1fe64dcc PH |
677 | notall1 bits to exclude from "all" for selector1 |
678 | notall2 bits to exclude from "all" for selector2 | |
059ec3d9 PH |
679 | string the configured string |
680 | options the table of option names | |
681 | count size of table | |
682 | which "log" or "debug" | |
683 | ||
684 | Returns: nothing on success - bomb out on failure | |
685 | */ | |
686 | ||
687 | static void | |
1fe64dcc PH |
688 | decode_bits(unsigned int *selector1, unsigned int *selector2, int notall1, |
689 | int notall2, uschar *string, bit_table *options, int count, uschar *which) | |
059ec3d9 PH |
690 | { |
691 | uschar *errmsg; | |
692 | if (string == NULL) return; | |
693 | ||
694 | if (*string == '=') | |
695 | { | |
696 | char *end; /* Not uschar */ | |
697 | *selector1 = strtoul(CS string+1, &end, 0); | |
698 | if (*end == 0) return; | |
699 | errmsg = string_sprintf("malformed numeric %s_selector setting: %s", which, | |
700 | string); | |
701 | goto ERROR_RETURN; | |
702 | } | |
703 | ||
704 | /* Handle symbolic setting */ | |
705 | ||
706 | else for(;;) | |
707 | { | |
708 | BOOL adding; | |
709 | uschar *s; | |
710 | int len; | |
711 | bit_table *start, *end; | |
712 | ||
713 | while (isspace(*string)) string++; | |
714 | if (*string == 0) return; | |
715 | ||
716 | if (*string != '+' && *string != '-') | |
717 | { | |
718 | errmsg = string_sprintf("malformed %s_selector setting: " | |
719 | "+ or - expected but found \"%s\"", which, string); | |
720 | goto ERROR_RETURN; | |
721 | } | |
722 | ||
723 | adding = *string++ == '+'; | |
724 | s = string; | |
725 | while (isalnum(*string) || *string == '_') string++; | |
726 | len = string - s; | |
727 | ||
728 | start = options; | |
729 | end = options + count; | |
730 | ||
731 | while (start < end) | |
732 | { | |
733 | bit_table *middle = start + (end - start)/2; | |
734 | int c = Ustrncmp(s, middle->name, len); | |
735 | if (c == 0) | |
736 | { | |
737 | if (middle->name[len] != 0) c = -1; else | |
738 | { | |
739 | unsigned int bit = middle->bit; | |
740 | unsigned int *selector; | |
741 | ||
1fe64dcc | 742 | /* The value with all bits set means "force all bits in both selectors" |
059ec3d9 | 743 | in the case where two are being handled. However, the top bit in the |
1fe64dcc PH |
744 | second selector is never set. When setting, some bits can be excluded. |
745 | */ | |
059ec3d9 PH |
746 | |
747 | if (bit == 0xffffffff) | |
748 | { | |
1fe64dcc PH |
749 | if (adding) |
750 | { | |
751 | *selector1 = 0xffffffff ^ notall1; | |
752 | if (selector2 != NULL) *selector2 = 0x7fffffff ^ notall2; | |
753 | } | |
754 | else | |
755 | { | |
756 | *selector1 = 0; | |
757 | if (selector2 != NULL) *selector2 = 0; | |
758 | } | |
059ec3d9 PH |
759 | } |
760 | ||
761 | /* Otherwise, the 0x80000000 bit means "this value, without the top | |
762 | bit, belongs in the second selector". */ | |
763 | ||
764 | else | |
765 | { | |
766 | if ((bit & 0x80000000) != 0) | |
767 | { | |
768 | selector = selector2; | |
769 | bit &= 0x7fffffff; | |
770 | } | |
771 | else selector = selector1; | |
772 | if (adding) *selector |= bit; else *selector &= ~bit; | |
773 | } | |
774 | break; /* Out of loop to match selector name */ | |
775 | } | |
776 | } | |
777 | if (c < 0) end = middle; else start = middle + 1; | |
778 | } /* Loop to match selector name */ | |
779 | ||
780 | if (start >= end) | |
781 | { | |
782 | errmsg = string_sprintf("unknown %s_selector setting: %c%.*s", which, | |
783 | adding? '+' : '-', len, s); | |
784 | goto ERROR_RETURN; | |
785 | } | |
786 | } /* Loop for selector names */ | |
787 | ||
788 | /* Handle disasters */ | |
789 | ||
790 | ERROR_RETURN: | |
791 | if (Ustrcmp(which, "debug") == 0) | |
792 | { | |
793 | fprintf(stderr, "exim: %s\n", errmsg); | |
794 | exit(EXIT_FAILURE); | |
795 | } | |
796 | else log_write(0, LOG_CONFIG|LOG_PANIC_DIE, "%s", errmsg); | |
797 | } | |
798 | ||
799 | ||
800 | ||
801 | /************************************************* | |
802 | * Show supported features * | |
803 | *************************************************/ | |
804 | ||
805 | /* This function is called for -bV and for -d to output the optional features | |
806 | of the current Exim binary. | |
807 | ||
808 | Arguments: a FILE for printing | |
809 | Returns: nothing | |
810 | */ | |
811 | ||
812 | static void | |
813 | show_whats_supported(FILE *f) | |
814 | { | |
815 | #ifdef DB_VERSION_STRING | |
816 | fprintf(f, "Berkeley DB: %s\n", DB_VERSION_STRING); | |
817 | #elif defined(BTREEVERSION) && defined(HASHVERSION) | |
818 | #ifdef USE_DB | |
819 | fprintf(f, "Probably Berkeley DB version 1.8x (native mode)\n"); | |
820 | #else | |
821 | fprintf(f, "Probably Berkeley DB version 1.8x (compatibility mode)\n"); | |
822 | #endif | |
823 | #elif defined(_DBM_RDONLY) || defined(dbm_dirfno) | |
824 | fprintf(f, "Probably ndbm\n"); | |
825 | #elif defined(USE_TDB) | |
826 | fprintf(f, "Using tdb\n"); | |
827 | #else | |
828 | #ifdef USE_GDBM | |
829 | fprintf(f, "Probably GDBM (native mode)\n"); | |
830 | #else | |
831 | fprintf(f, "Probably GDBM (compatibility mode)\n"); | |
832 | #endif | |
833 | #endif | |
834 | ||
835 | fprintf(f, "Support for:"); | |
9cec981f PH |
836 | #ifdef SUPPORT_CRYPTEQ |
837 | fprintf(f, " crypteq"); | |
838 | #endif | |
059ec3d9 PH |
839 | #if HAVE_ICONV |
840 | fprintf(f, " iconv()"); | |
841 | #endif | |
842 | #if HAVE_IPV6 | |
843 | fprintf(f, " IPv6"); | |
844 | #endif | |
929ba01c PH |
845 | #ifdef HAVE_LOGIN_CAP |
846 | fprintf(f, " use_classresources"); | |
847 | #endif | |
059ec3d9 PH |
848 | #ifdef SUPPORT_PAM |
849 | fprintf(f, " PAM"); | |
850 | #endif | |
851 | #ifdef EXIM_PERL | |
852 | fprintf(f, " Perl"); | |
853 | #endif | |
1a46a8c5 PH |
854 | #ifdef EXPAND_DLFUNC |
855 | fprintf(f, " Expand_dlfunc"); | |
856 | #endif | |
059ec3d9 PH |
857 | #ifdef USE_TCP_WRAPPERS |
858 | fprintf(f, " TCPwrappers"); | |
859 | #endif | |
860 | #ifdef SUPPORT_TLS | |
861 | #ifdef USE_GNUTLS | |
862 | fprintf(f, " GnuTLS"); | |
863 | #else | |
864 | fprintf(f, " OpenSSL"); | |
865 | #endif | |
866 | #endif | |
b2f5a032 PH |
867 | #ifdef SUPPORT_TRANSLATE_IP_ADDRESS |
868 | fprintf(f, " translate_ip_address"); | |
869 | #endif | |
f174f16e PH |
870 | #ifdef SUPPORT_MOVE_FROZEN_MESSAGES |
871 | fprintf(f, " move_frozen_messages"); | |
872 | #endif | |
8523533c TK |
873 | #ifdef WITH_CONTENT_SCAN |
874 | fprintf(f, " Content_Scanning"); | |
875 | #endif | |
876 | #ifdef WITH_OLD_DEMIME | |
877 | fprintf(f, " Old_Demime"); | |
878 | #endif | |
879 | #ifdef EXPERIMENTAL_SPF | |
880 | fprintf(f, " Experimental_SPF"); | |
881 | #endif | |
882 | #ifdef EXPERIMENTAL_SRS | |
883 | fprintf(f, " Experimental_SRS"); | |
884 | #endif | |
885 | #ifdef EXPERIMENTAL_BRIGHTMAIL | |
886 | fprintf(f, " Experimental_Brightmail"); | |
887 | #endif | |
fb2274d4 TK |
888 | #ifdef EXPERIMENTAL_DOMAINKEYS |
889 | fprintf(f, " Experimental_DomainKeys"); | |
890 | #endif | |
059ec3d9 PH |
891 | fprintf(f, "\n"); |
892 | ||
893 | fprintf(f, "Lookups:"); | |
894 | #ifdef LOOKUP_LSEARCH | |
895 | fprintf(f, " lsearch wildlsearch nwildlsearch iplsearch"); | |
896 | #endif | |
897 | #ifdef LOOKUP_CDB | |
898 | fprintf(f, " cdb"); | |
899 | #endif | |
900 | #ifdef LOOKUP_DBM | |
901 | fprintf(f, " dbm dbmnz"); | |
902 | #endif | |
903 | #ifdef LOOKUP_DNSDB | |
904 | fprintf(f, " dnsdb"); | |
905 | #endif | |
906 | #ifdef LOOKUP_DSEARCH | |
907 | fprintf(f, " dsearch"); | |
908 | #endif | |
909 | #ifdef LOOKUP_IBASE | |
910 | fprintf(f, " ibase"); | |
911 | #endif | |
912 | #ifdef LOOKUP_LDAP | |
913 | fprintf(f, " ldap ldapdn ldapm"); | |
914 | #endif | |
915 | #ifdef LOOKUP_MYSQL | |
916 | fprintf(f, " mysql"); | |
917 | #endif | |
918 | #ifdef LOOKUP_NIS | |
919 | fprintf(f, " nis nis0"); | |
920 | #endif | |
921 | #ifdef LOOKUP_NISPLUS | |
922 | fprintf(f, " nisplus"); | |
923 | #endif | |
924 | #ifdef LOOKUP_ORACLE | |
925 | fprintf(f, " oracle"); | |
926 | #endif | |
927 | #ifdef LOOKUP_PASSWD | |
928 | fprintf(f, " passwd"); | |
929 | #endif | |
930 | #ifdef LOOKUP_PGSQL | |
931 | fprintf(f, " pgsql"); | |
932 | #endif | |
13b685f9 PH |
933 | #ifdef LOOKUP_SQLITE |
934 | fprintf(f, " sqlite"); | |
935 | #endif | |
059ec3d9 PH |
936 | #ifdef LOOKUP_TESTDB |
937 | fprintf(f, " testdb"); | |
938 | #endif | |
939 | #ifdef LOOKUP_WHOSON | |
940 | fprintf(f, " whoson"); | |
941 | #endif | |
942 | fprintf(f, "\n"); | |
943 | ||
944 | fprintf(f, "Authenticators:"); | |
945 | #ifdef AUTH_CRAM_MD5 | |
946 | fprintf(f, " cram_md5"); | |
947 | #endif | |
948 | #ifdef AUTH_CYRUS_SASL | |
949 | fprintf(f, " cyrus_sasl"); | |
950 | #endif | |
951 | #ifdef AUTH_PLAINTEXT | |
952 | fprintf(f, " plaintext"); | |
953 | #endif | |
954 | #ifdef AUTH_SPA | |
955 | fprintf(f, " spa"); | |
956 | #endif | |
957 | fprintf(f, "\n"); | |
958 | ||
959 | fprintf(f, "Routers:"); | |
960 | #ifdef ROUTER_ACCEPT | |
961 | fprintf(f, " accept"); | |
962 | #endif | |
963 | #ifdef ROUTER_DNSLOOKUP | |
964 | fprintf(f, " dnslookup"); | |
965 | #endif | |
966 | #ifdef ROUTER_IPLITERAL | |
967 | fprintf(f, " ipliteral"); | |
968 | #endif | |
969 | #ifdef ROUTER_IPLOOKUP | |
970 | fprintf(f, " iplookup"); | |
971 | #endif | |
972 | #ifdef ROUTER_MANUALROUTE | |
973 | fprintf(f, " manualroute"); | |
974 | #endif | |
975 | #ifdef ROUTER_QUERYPROGRAM | |
976 | fprintf(f, " queryprogram"); | |
977 | #endif | |
978 | #ifdef ROUTER_REDIRECT | |
979 | fprintf(f, " redirect"); | |
980 | #endif | |
981 | fprintf(f, "\n"); | |
982 | ||
983 | fprintf(f, "Transports:"); | |
984 | #ifdef TRANSPORT_APPENDFILE | |
985 | fprintf(f, " appendfile"); | |
986 | #ifdef SUPPORT_MAILDIR | |
987 | fprintf(f, "/maildir"); | |
988 | #endif | |
989 | #ifdef SUPPORT_MAILSTORE | |
990 | fprintf(f, "/mailstore"); | |
991 | #endif | |
992 | #ifdef SUPPORT_MBX | |
993 | fprintf(f, "/mbx"); | |
994 | #endif | |
995 | #endif | |
996 | #ifdef TRANSPORT_AUTOREPLY | |
997 | fprintf(f, " autoreply"); | |
998 | #endif | |
999 | #ifdef TRANSPORT_LMTP | |
1000 | fprintf(f, " lmtp"); | |
1001 | #endif | |
1002 | #ifdef TRANSPORT_PIPE | |
1003 | fprintf(f, " pipe"); | |
1004 | #endif | |
1005 | #ifdef TRANSPORT_SMTP | |
1006 | fprintf(f, " smtp"); | |
1007 | #endif | |
1008 | fprintf(f, "\n"); | |
1009 | ||
1010 | if (fixed_never_users[0] > 0) | |
1011 | { | |
1012 | int i; | |
1013 | fprintf(f, "Fixed never_users: "); | |
1014 | for (i = 1; i <= (int)fixed_never_users[0] - 1; i++) | |
1015 | fprintf(f, "%d:", (unsigned int)fixed_never_users[i]); | |
1016 | fprintf(f, "%d\n", (unsigned int)fixed_never_users[i]); | |
1017 | } | |
21c28500 PH |
1018 | |
1019 | fprintf(f, "Size of off_t: %d\n", sizeof(off_t)); | |
059ec3d9 PH |
1020 | } |
1021 | ||
1022 | ||
1023 | ||
1024 | ||
1025 | /************************************************* | |
1026 | * Quote a local part * | |
1027 | *************************************************/ | |
1028 | ||
1029 | /* This function is used when a sender address or a From: or Sender: header | |
1030 | line is being created from the caller's login, or from an authenticated_id. It | |
1031 | applies appropriate quoting rules for a local part. | |
1032 | ||
1033 | Argument: the local part | |
1034 | Returns: the local part, quoted if necessary | |
1035 | */ | |
1036 | ||
1037 | uschar * | |
1038 | local_part_quote(uschar *lpart) | |
1039 | { | |
1040 | BOOL needs_quote = FALSE; | |
1041 | int size, ptr; | |
1042 | uschar *yield; | |
1043 | uschar *t; | |
1044 | ||
1045 | for (t = lpart; !needs_quote && *t != 0; t++) | |
1046 | { | |
1047 | needs_quote = !isalnum(*t) && strchr("!#$%&'*+-/=?^_`{|}~", *t) == NULL && | |
1048 | (*t != '.' || t == lpart || t[1] == 0); | |
1049 | } | |
1050 | ||
1051 | if (!needs_quote) return lpart; | |
1052 | ||
1053 | size = ptr = 0; | |
1054 | yield = string_cat(NULL, &size, &ptr, US"\"", 1); | |
1055 | ||
1056 | for (;;) | |
1057 | { | |
1058 | uschar *nq = US Ustrpbrk(lpart, "\\\""); | |
1059 | if (nq == NULL) | |
1060 | { | |
1061 | yield = string_cat(yield, &size, &ptr, lpart, Ustrlen(lpart)); | |
1062 | break; | |
1063 | } | |
1064 | yield = string_cat(yield, &size, &ptr, lpart, nq - lpart); | |
1065 | yield = string_cat(yield, &size, &ptr, US"\\", 1); | |
1066 | yield = string_cat(yield, &size, &ptr, nq, 1); | |
1067 | lpart = nq + 1; | |
1068 | } | |
1069 | ||
1070 | yield = string_cat(yield, &size, &ptr, US"\"", 1); | |
1071 | yield[ptr] = 0; | |
1072 | return yield; | |
1073 | } | |
1074 | ||
1075 | ||
1076 | ||
1077 | #ifdef USE_READLINE | |
1078 | /************************************************* | |
1079 | * Load readline() functions * | |
1080 | *************************************************/ | |
1081 | ||
1082 | /* This function is called from testing executions that read data from stdin, | |
1083 | but only when running as the calling user. Currently, only -be does this. The | |
1084 | function loads the readline() function library and passes back the functions. | |
1085 | On some systems, it needs the curses library, so load that too, but try without | |
1086 | it if loading fails. All this functionality has to be requested at build time. | |
1087 | ||
1088 | Arguments: | |
1089 | fn_readline_ptr pointer to where to put the readline pointer | |
1090 | fn_addhist_ptr pointer to where to put the addhistory function | |
1091 | ||
1092 | Returns: the dlopen handle or NULL on failure | |
1093 | */ | |
1094 | ||
1095 | static void * | |
1096 | set_readline(char * (**fn_readline_ptr)(char *), | |
1097 | char * (**fn_addhist_ptr)(char *)) | |
1098 | { | |
1099 | void *dlhandle; | |
1100 | void *dlhandle_curses = dlopen("libcurses.so", RTLD_GLOBAL|RTLD_LAZY); | |
1101 | ||
1102 | dlhandle = dlopen("libreadline.so", RTLD_GLOBAL|RTLD_NOW); | |
1103 | if (dlhandle_curses != NULL) dlclose(dlhandle_curses); | |
1104 | ||
1105 | if (dlhandle != NULL) | |
1106 | { | |
1107 | *fn_readline_ptr = (char *(*)(char*))dlsym(dlhandle, "readline"); | |
1108 | *fn_addhist_ptr = (char *(*)(char*))dlsym(dlhandle, "add_history"); | |
1109 | } | |
1110 | else | |
1111 | { | |
1112 | DEBUG(D_any) debug_printf("failed to load readline: %s\n", dlerror()); | |
1113 | } | |
1114 | ||
1115 | return dlhandle; | |
1116 | } | |
1117 | #endif | |
1118 | ||
1119 | ||
1120 | ||
1121 | /************************************************* | |
1122 | * Get a line from stdin for testing things * | |
1123 | *************************************************/ | |
1124 | ||
1125 | /* This function is called when running tests that can take a number of lines | |
1126 | of input (for example, -be and -bt). It handles continuations and trailing | |
1127 | spaces. And prompting and a blank line output on eof. If readline() is in use, | |
1128 | the arguments are non-NULL and provide the relevant functions. | |
1129 | ||
1130 | Arguments: | |
1131 | fn_readline readline function or NULL | |
1132 | fn_addhist addhist function or NULL | |
1133 | ||
1134 | Returns: pointer to dynamic memory, or NULL at end of file | |
1135 | */ | |
1136 | ||
1137 | static uschar * | |
1138 | get_stdinput(char *(*fn_readline)(char *), char *(*fn_addhist)(char *)) | |
1139 | { | |
1140 | int i; | |
1141 | int size = 0; | |
1142 | int ptr = 0; | |
1143 | uschar *yield = NULL; | |
1144 | ||
1145 | if (fn_readline == NULL) printf("> "); | |
1146 | ||
1147 | for (i = 0;; i++) | |
1148 | { | |
1149 | uschar buffer[1024]; | |
1150 | uschar *p, *ss; | |
1151 | ||
1152 | #ifdef USE_READLINE | |
1153 | char *readline_line = NULL; | |
1154 | if (fn_readline != NULL) | |
1155 | { | |
1156 | if ((readline_line = fn_readline((i > 0)? "":"> ")) == NULL) break; | |
1157 | if (*readline_line != 0 && fn_addhist != NULL) fn_addhist(readline_line); | |
1158 | p = US readline_line; | |
1159 | } | |
1160 | else | |
1161 | #endif | |
1162 | ||
1163 | /* readline() not in use */ | |
1164 | ||
1165 | { | |
1166 | if (Ufgets(buffer, sizeof(buffer), stdin) == NULL) break; | |
1167 | p = buffer; | |
1168 | } | |
1169 | ||
1170 | /* Handle the line */ | |
1171 | ||
1172 | ss = p + (int)Ustrlen(p); | |
1173 | while (ss > p && isspace(ss[-1])) ss--; | |
1174 | ||
1175 | if (i > 0) | |
1176 | { | |
1177 | while (p < ss && isspace(*p)) p++; /* leading space after cont */ | |
1178 | } | |
1179 | ||
1180 | yield = string_cat(yield, &size, &ptr, p, ss - p); | |
1181 | ||
1182 | #ifdef USE_READLINE | |
1183 | if (fn_readline != NULL) free(readline_line); | |
1184 | #endif | |
1185 | ||
1186 | if (ss == p || yield[ptr-1] != '\\') | |
1187 | { | |
1188 | yield[ptr] = 0; | |
1189 | break; | |
1190 | } | |
1191 | yield[--ptr] = 0; | |
1192 | } | |
1193 | ||
1194 | if (yield == NULL) printf("\n"); | |
1195 | return yield; | |
1196 | } | |
1197 | ||
1198 | ||
1199 | ||
1200 | /************************************************* | |
1201 | * Entry point and high-level code * | |
1202 | *************************************************/ | |
1203 | ||
1204 | /* Entry point for the Exim mailer. Analyse the arguments and arrange to take | |
1205 | the appropriate action. All the necessary functions are present in the one | |
1206 | binary. I originally thought one should split it up, but it turns out that so | |
1207 | much of the apparatus is needed in each chunk that one might as well just have | |
1208 | it all available all the time, which then makes the coding easier as well. | |
1209 | ||
1210 | Arguments: | |
1211 | argc count of entries in argv | |
1212 | argv argument strings, with argv[0] being the program name | |
1213 | ||
1214 | Returns: EXIT_SUCCESS if terminated successfully | |
1215 | EXIT_FAILURE otherwise, except when a message has been sent | |
1216 | to the sender, and -oee was given | |
1217 | */ | |
1218 | ||
1219 | int | |
1220 | main(int argc, char **cargv) | |
1221 | { | |
1222 | uschar **argv = USS cargv; | |
1223 | int arg_receive_timeout = -1; | |
1224 | int arg_smtp_receive_timeout = -1; | |
1225 | int arg_error_handling = error_handling; | |
f05da2e8 PH |
1226 | int filter_sfd = -1; |
1227 | int filter_ufd = -1; | |
059ec3d9 PH |
1228 | int group_count; |
1229 | int i; | |
1230 | int list_queue_option = 0; | |
1231 | int msg_action = 0; | |
1232 | int msg_action_arg = -1; | |
1233 | int namelen = (argv[0] == NULL)? 0 : Ustrlen(argv[0]); | |
1234 | int queue_only_reason = 0; | |
1235 | #ifdef EXIM_PERL | |
1236 | int perl_start_option = 0; | |
1237 | #endif | |
1238 | int recipients_arg = argc; | |
1239 | int sender_address_domain = 0; | |
1240 | int test_retry_arg = -1; | |
1241 | int test_rewrite_arg = -1; | |
1242 | BOOL arg_queue_only = FALSE; | |
1243 | BOOL bi_option = FALSE; | |
1244 | BOOL checking = FALSE; | |
1245 | BOOL count_queue = FALSE; | |
1246 | BOOL expansion_test = FALSE; | |
1247 | BOOL extract_recipients = FALSE; | |
1248 | BOOL forced_delivery = FALSE; | |
1249 | BOOL f_end_dot = FALSE; | |
1250 | BOOL deliver_give_up = FALSE; | |
1251 | BOOL list_queue = FALSE; | |
1252 | BOOL list_options = FALSE; | |
1253 | BOOL local_queue_only; | |
1254 | BOOL more = TRUE; | |
1255 | BOOL one_msg_action = FALSE; | |
1256 | BOOL queue_only_set = FALSE; | |
1257 | BOOL receiving_message = TRUE; | |
1258 | BOOL unprivileged; | |
1259 | BOOL removed_privilege = FALSE; | |
1260 | BOOL verify_address_mode = FALSE; | |
1261 | BOOL verify_as_sender = FALSE; | |
1262 | BOOL version_printed = FALSE; | |
1263 | uschar *alias_arg = NULL; | |
1264 | uschar *called_as = US""; | |
1265 | uschar *start_queue_run_id = NULL; | |
1266 | uschar *stop_queue_run_id = NULL; | |
1267 | uschar *ftest_domain = NULL; | |
1268 | uschar *ftest_localpart = NULL; | |
1269 | uschar *ftest_prefix = NULL; | |
1270 | uschar *ftest_suffix = NULL; | |
1271 | uschar *real_sender_address; | |
1272 | uschar *originator_home = US"/"; | |
059ec3d9 PH |
1273 | void *reset_point; |
1274 | ||
1275 | struct passwd *pw; | |
1276 | struct stat statbuf; | |
1277 | pid_t passed_qr_pid = (pid_t)0; | |
1278 | int passed_qr_pipe = -1; | |
1279 | gid_t group_list[NGROUPS_MAX]; | |
1280 | ||
1281 | /* Possible options for -R and -S */ | |
1282 | ||
1283 | static uschar *rsopts[] = { US"f", US"ff", US"r", US"rf", US"rff" }; | |
1284 | ||
1285 | /* Need to define this in case we need to change the environment in order | |
1286 | to get rid of a bogus time zone. We have to make it char rather than uschar | |
1287 | because some OS define it in /usr/include/unistd.h. */ | |
1288 | ||
1289 | extern char **environ; | |
1290 | ||
35edf2ff | 1291 | /* If the Exim user and/or group and/or the configuration file owner/group were |
059ec3d9 PH |
1292 | defined by ref:name at build time, we must now find the actual uid/gid values. |
1293 | This is a feature to make the lives of binary distributors easier. */ | |
1294 | ||
1295 | #ifdef EXIM_USERNAME | |
1296 | if (route_finduser(US EXIM_USERNAME, &pw, &exim_uid)) | |
1297 | { | |
1298 | exim_gid = pw->pw_gid; | |
1299 | } | |
1300 | else | |
1301 | { | |
1302 | fprintf(stderr, "exim: failed to find uid for user name \"%s\"\n", | |
1303 | EXIM_USERNAME); | |
1304 | exit(EXIT_FAILURE); | |
1305 | } | |
1306 | #endif | |
1307 | ||
1308 | #ifdef EXIM_GROUPNAME | |
1309 | if (!route_findgroup(US EXIM_GROUPNAME, &exim_gid)) | |
1310 | { | |
1311 | fprintf(stderr, "exim: failed to find gid for group name \"%s\"\n", | |
1312 | EXIM_GROUPNAME); | |
1313 | exit(EXIT_FAILURE); | |
1314 | } | |
1315 | #endif | |
1316 | ||
1317 | #ifdef CONFIGURE_OWNERNAME | |
1318 | if (!route_finduser(US CONFIGURE_OWNERNAME, NULL, &config_uid)) | |
1319 | { | |
1320 | fprintf(stderr, "exim: failed to find uid for user name \"%s\"\n", | |
1321 | CONFIGURE_OWNERNAME); | |
1322 | exit(EXIT_FAILURE); | |
1323 | } | |
1324 | #endif | |
1325 | ||
35edf2ff PH |
1326 | #ifdef CONFIGURE_GROUPNAME |
1327 | if (!route_findgroup(US CONFIGURE_GROUPNAME, &config_gid)) | |
1328 | { | |
1329 | fprintf(stderr, "exim: failed to find gid for group name \"%s\"\n", | |
1330 | CONFIGURE_GROUPNAME); | |
1331 | exit(EXIT_FAILURE); | |
1332 | } | |
1333 | #endif | |
1334 | ||
059ec3d9 PH |
1335 | /* In the Cygwin environment, some initialization needs doing. It is fudged |
1336 | in by means of this macro. */ | |
1337 | ||
1338 | #ifdef OS_INIT | |
1339 | OS_INIT | |
1340 | #endif | |
1341 | ||
1342 | /* Check a field which is patched when we are running Exim within its | |
1343 | testing harness; do a fast initial check, and then the whole thing. */ | |
1344 | ||
1345 | running_in_test_harness = | |
1346 | *running_status == '<' && Ustrcmp(running_status, "<<<testing>>>") == 0; | |
1347 | ||
1348 | /* The C standard says that the equivalent of setlocale(LC_ALL, "C") is obeyed | |
1349 | at the start of a program; however, it seems that some environments do not | |
1350 | follow this. A "strange" locale can affect the formatting of timestamps, so we | |
1351 | make quite sure. */ | |
1352 | ||
1353 | setlocale(LC_ALL, "C"); | |
1354 | ||
1355 | /* Set up the default handler for timing using alarm(). */ | |
1356 | ||
1357 | os_non_restarting_signal(SIGALRM, sigalrm_handler); | |
1358 | ||
1359 | /* Ensure we have a buffer for constructing log entries. Use malloc directly, | |
1360 | because store_malloc writes a log entry on failure. */ | |
1361 | ||
1362 | log_buffer = (uschar *)malloc(LOG_BUFFER_SIZE); | |
1363 | if (log_buffer == NULL) | |
1364 | { | |
1365 | fprintf(stderr, "exim: failed to get store for log buffer\n"); | |
1366 | exit(EXIT_FAILURE); | |
1367 | } | |
1368 | ||
1369 | /* Set log_stderr to stderr, provided that stderr exists. This gets reset to | |
1370 | NULL when the daemon is run and the file is closed. We have to use this | |
1371 | indirection, because some systems don't allow writing to the variable "stderr". | |
1372 | */ | |
1373 | ||
1374 | if (fstat(fileno(stderr), &statbuf) >= 0) log_stderr = stderr; | |
1375 | ||
1376 | /* Arrange for the PCRE regex library to use our store functions. Note that | |
1377 | the normal calls are actually macros that add additional arguments for | |
1378 | debugging purposes so we have to assign specially constructed functions here. | |
1379 | The default is to use store in the stacking pool, but this is overridden in the | |
1380 | regex_must_compile() function. */ | |
1381 | ||
1382 | pcre_malloc = function_store_get; | |
1383 | pcre_free = function_dummy_free; | |
1384 | ||
1385 | /* Ensure there is a big buffer for temporary use in several places. It is put | |
1386 | in malloc store so that it can be freed for enlargement if necessary. */ | |
1387 | ||
1388 | big_buffer = store_malloc(big_buffer_size); | |
1389 | ||
1390 | /* Set up the handler for the data request signal, and set the initial | |
1391 | descriptive text. */ | |
1392 | ||
1393 | set_process_info("initializing"); | |
1394 | os_restarting_signal(SIGUSR1, usr1_handler); | |
1395 | ||
1396 | /* SIGHUP is used to get the daemon to reconfigure. It gets set as appropriate | |
1397 | in the daemon code. For the rest of Exim's uses, we ignore it. */ | |
1398 | ||
1399 | signal(SIGHUP, SIG_IGN); | |
1400 | ||
1401 | /* We don't want to die on pipe errors as the code is written to handle | |
1402 | the write error instead. */ | |
1403 | ||
1404 | signal(SIGPIPE, SIG_IGN); | |
1405 | ||
1406 | /* Under some circumstance on some OS, Exim can get called with SIGCHLD | |
1407 | set to SIG_IGN. This causes subprocesses that complete before the parent | |
1408 | process waits for them not to hang around, so when Exim calls wait(), nothing | |
1409 | is there. The wait() code has been made robust against this, but let's ensure | |
1410 | that SIGCHLD is set to SIG_DFL, because it's tidier to wait and get a process | |
1411 | ending status. We use sigaction rather than plain signal() on those OS where | |
1412 | SA_NOCLDWAIT exists, because we want to be sure it is turned off. (There was a | |
1413 | problem on AIX with this.) */ | |
1414 | ||
1415 | #ifdef SA_NOCLDWAIT | |
1416 | { | |
1417 | struct sigaction act; | |
1418 | act.sa_handler = SIG_DFL; | |
1419 | sigemptyset(&(act.sa_mask)); | |
1420 | act.sa_flags = 0; | |
1421 | sigaction(SIGCHLD, &act, NULL); | |
1422 | } | |
1423 | #else | |
1424 | signal(SIGCHLD, SIG_DFL); | |
1425 | #endif | |
1426 | ||
1427 | /* Save the arguments for use if we re-exec exim as a daemon after receiving | |
1428 | SIGHUP. */ | |
1429 | ||
1430 | sighup_argv = argv; | |
1431 | ||
1432 | /* Set up the version number. Set up the leading 'E' for the external form of | |
1433 | message ids, set the pointer to the internal form, and initialize it to | |
1434 | indicate no message being processed. */ | |
1435 | ||
1436 | version_init(); | |
1437 | message_id_option[0] = '-'; | |
1438 | message_id_external = message_id_option + 1; | |
1439 | message_id_external[0] = 'E'; | |
1440 | message_id = message_id_external + 1; | |
1441 | message_id[0] = 0; | |
1442 | ||
1443 | /* Set the umask to zero so that any files that Exim creates are created | |
1444 | with the modes that it specifies. */ | |
1445 | ||
1446 | umask(0); | |
1447 | ||
1448 | /* Precompile the regular expression for matching a message id. Keep this in | |
1449 | step with the code that generates ids in the accept.c module. We need to do | |
1450 | this here, because the -M options check their arguments for syntactic validity | |
1451 | using mac_ismsgid, which uses this. */ | |
1452 | ||
1453 | regex_ismsgid = | |
1454 | regex_must_compile(US"^(?:[^\\W_]{6}-){2}[^\\W_]{2}$", FALSE, TRUE); | |
1455 | ||
1456 | /* If the program is called as "mailq" treat it as equivalent to "exim -bp"; | |
1457 | this seems to be a generally accepted convention, since one finds symbolic | |
1458 | links called "mailq" in standard OS configurations. */ | |
1459 | ||
1460 | if ((namelen == 5 && Ustrcmp(argv[0], "mailq") == 0) || | |
1461 | (namelen > 5 && Ustrncmp(argv[0] + namelen - 6, "/mailq", 6) == 0)) | |
1462 | { | |
1463 | list_queue = TRUE; | |
1464 | receiving_message = FALSE; | |
1465 | called_as = US"-mailq"; | |
1466 | } | |
1467 | ||
1468 | /* If the program is called as "rmail" treat it as equivalent to | |
1469 | "exim -i -oee", thus allowing UUCP messages to be input using non-SMTP mode, | |
1470 | i.e. preventing a single dot on a line from terminating the message, and | |
1471 | returning with zero return code, even in cases of error (provided an error | |
1472 | message has been sent). */ | |
1473 | ||
1474 | if ((namelen == 5 && Ustrcmp(argv[0], "rmail") == 0) || | |
1475 | (namelen > 5 && Ustrncmp(argv[0] + namelen - 6, "/rmail", 6) == 0)) | |
1476 | { | |
1477 | dot_ends = FALSE; | |
1478 | called_as = US"-rmail"; | |
1479 | errors_sender_rc = EXIT_SUCCESS; | |
1480 | } | |
1481 | ||
1482 | /* If the program is called as "rsmtp" treat it as equivalent to "exim -bS"; | |
1483 | this is a smail convention. */ | |
1484 | ||
1485 | if ((namelen == 5 && Ustrcmp(argv[0], "rsmtp") == 0) || | |
1486 | (namelen > 5 && Ustrncmp(argv[0] + namelen - 6, "/rsmtp", 6) == 0)) | |
1487 | { | |
1488 | smtp_input = smtp_batched_input = TRUE; | |
1489 | called_as = US"-rsmtp"; | |
1490 | } | |
1491 | ||
1492 | /* If the program is called as "runq" treat it as equivalent to "exim -q"; | |
1493 | this is a smail convention. */ | |
1494 | ||
1495 | if ((namelen == 4 && Ustrcmp(argv[0], "runq") == 0) || | |
1496 | (namelen > 4 && Ustrncmp(argv[0] + namelen - 5, "/runq", 5) == 0)) | |
1497 | { | |
1498 | queue_interval = 0; | |
1499 | receiving_message = FALSE; | |
1500 | called_as = US"-runq"; | |
1501 | } | |
1502 | ||
1503 | /* If the program is called as "newaliases" treat it as equivalent to | |
1504 | "exim -bi"; this is a sendmail convention. */ | |
1505 | ||
1506 | if ((namelen == 10 && Ustrcmp(argv[0], "newaliases") == 0) || | |
1507 | (namelen > 10 && Ustrncmp(argv[0] + namelen - 11, "/newaliases", 11) == 0)) | |
1508 | { | |
1509 | bi_option = TRUE; | |
1510 | receiving_message = FALSE; | |
1511 | called_as = US"-newaliases"; | |
1512 | } | |
1513 | ||
1514 | /* Save the original effective uid for a couple of uses later. It should | |
1515 | normally be root, but in some esoteric environments it may not be. */ | |
1516 | ||
1517 | original_euid = geteuid(); | |
1518 | ||
1519 | /* Get the real uid and gid. If the caller is root, force the effective uid/gid | |
1520 | to be the same as the real ones. This makes a difference only if Exim is setuid | |
1521 | (or setgid) to something other than root, which could be the case in some | |
1522 | special configurations. */ | |
1523 | ||
1524 | real_uid = getuid(); | |
1525 | real_gid = getgid(); | |
1526 | ||
1527 | if (real_uid == root_uid) | |
1528 | { | |
1529 | setgid(real_gid); | |
1530 | setuid(real_uid); | |
1531 | } | |
1532 | ||
1533 | /* If neither the original real uid nor the original euid was root, Exim is | |
1534 | running in an unprivileged state. */ | |
1535 | ||
1536 | unprivileged = (real_uid != root_uid && original_euid != root_uid); | |
1537 | ||
1538 | /* If the first argument is --help, pretend there are no arguments. This will | |
1539 | cause a brief message to be given. */ | |
1540 | ||
1541 | if (argc > 1 && Ustrcmp(argv[1], "--help") == 0) argc = 1; | |
1542 | ||
1543 | /* Scan the program's arguments. Some can be dealt with right away; others are | |
1544 | simply recorded for checking and handling afterwards. Do a high-level switch | |
1545 | on the second character (the one after '-'), to save some effort. */ | |
1546 | ||
1547 | for (i = 1; i < argc; i++) | |
1548 | { | |
1549 | BOOL badarg = FALSE; | |
1550 | uschar *arg = argv[i]; | |
1551 | uschar *argrest; | |
1552 | int switchchar; | |
1553 | ||
1554 | /* An argument not starting with '-' is the start of a recipients list; | |
1555 | break out of the options-scanning loop. */ | |
1556 | ||
1557 | if (arg[0] != '-') | |
1558 | { | |
1559 | recipients_arg = i; | |
1560 | break; | |
1561 | } | |
1562 | ||
1563 | /* An option consistion of -- terminates the options */ | |
1564 | ||
1565 | if (Ustrcmp(arg, "--") == 0) | |
1566 | { | |
1567 | recipients_arg = i + 1; | |
1568 | break; | |
1569 | } | |
1570 | ||
1571 | /* Handle flagged options */ | |
1572 | ||
1573 | switchchar = arg[1]; | |
1574 | argrest = arg+2; | |
1575 | ||
1576 | /* Make all -ex options synonymous with -oex arguments, since that | |
1577 | is assumed by various callers. Also make -qR options synonymous with -R | |
1578 | options, as that seems to be required as well. Allow for -qqR too, and | |
1579 | the same for -S options. */ | |
1580 | ||
1581 | if (Ustrncmp(arg+1, "oe", 2) == 0 || | |
1582 | Ustrncmp(arg+1, "qR", 2) == 0 || | |
1583 | Ustrncmp(arg+1, "qS", 2) == 0) | |
1584 | { | |
1585 | switchchar = arg[2]; | |
1586 | argrest++; | |
1587 | } | |
1588 | else if (Ustrncmp(arg+1, "qqR", 3) == 0 || Ustrncmp(arg+1, "qqS", 3) == 0) | |
1589 | { | |
1590 | switchchar = arg[3]; | |
1591 | argrest += 2; | |
1592 | queue_2stage = TRUE; | |
1593 | } | |
1594 | ||
1595 | /* Make -r synonymous with -f, since it is a documented alias */ | |
1596 | ||
1597 | else if (arg[1] == 'r') switchchar = 'f'; | |
1598 | ||
1599 | /* Make -ov synonymous with -v */ | |
1600 | ||
1601 | else if (Ustrcmp(arg, "-ov") == 0) | |
1602 | { | |
1603 | switchchar = 'v'; | |
1604 | argrest++; | |
1605 | } | |
1606 | ||
1607 | /* High-level switch on active initial letter */ | |
1608 | ||
1609 | switch(switchchar) | |
1610 | { | |
1611 | /* -Btype is a sendmail option for 7bit/8bit setting. Exim is 8-bit clean | |
1612 | so has no need of it. */ | |
1613 | ||
1614 | case 'B': | |
1615 | if (*argrest == 0) i++; /* Skip over the type */ | |
1616 | break; | |
1617 | ||
1618 | ||
1619 | case 'b': | |
1620 | receiving_message = FALSE; /* Reset TRUE for -bm, -bS, -bs below */ | |
1621 | ||
1622 | /* -bd: Run in daemon mode, awaiting SMTP connections. | |
1623 | -bdf: Ditto, but in the foreground. | |
1624 | */ | |
1625 | ||
1626 | if (*argrest == 'd') | |
1627 | { | |
1628 | daemon_listen = TRUE; | |
1629 | if (*(++argrest) == 'f') background_daemon = FALSE; | |
1630 | else if (*argrest != 0) { badarg = TRUE; break; } | |
1631 | } | |
1632 | ||
1633 | /* -be: Run in expansion test mode */ | |
1634 | ||
1635 | else if (*argrest == 'e') | |
1636 | expansion_test = checking = TRUE; | |
1637 | ||
f05da2e8 PH |
1638 | /* -bF: Run system filter test */ |
1639 | ||
1640 | else if (*argrest == 'F') | |
1641 | { | |
1642 | filter_test |= FTEST_SYSTEM; | |
1643 | if (*(++argrest) != 0) { badarg = TRUE; break; } | |
1644 | if (++i < argc) filter_test_sfile = argv[i]; else | |
1645 | { | |
1646 | fprintf(stderr, "exim: file name expected after %s\n", argv[i-1]); | |
1647 | exit(EXIT_FAILURE); | |
1648 | } | |
1649 | } | |
1650 | ||
1651 | /* -bf: Run user filter test | |
059ec3d9 PH |
1652 | -bfd: Set domain for filter testing |
1653 | -bfl: Set local part for filter testing | |
1654 | -bfp: Set prefix for filter testing | |
1655 | -bfs: Set suffix for filter testing | |
1656 | */ | |
1657 | ||
f05da2e8 | 1658 | else if (*argrest == 'f') |
059ec3d9 | 1659 | { |
f05da2e8 | 1660 | if (*(++argrest) == 0) |
059ec3d9 | 1661 | { |
f05da2e8 PH |
1662 | filter_test |= FTEST_USER; |
1663 | if (++i < argc) filter_test_ufile = argv[i]; else | |
059ec3d9 PH |
1664 | { |
1665 | fprintf(stderr, "exim: file name expected after %s\n", argv[i-1]); | |
1666 | exit(EXIT_FAILURE); | |
1667 | } | |
1668 | } | |
1669 | else | |
1670 | { | |
1671 | if (++i >= argc) | |
1672 | { | |
1673 | fprintf(stderr, "exim: string expected after %s\n", arg); | |
1674 | exit(EXIT_FAILURE); | |
1675 | } | |
1676 | if (Ustrcmp(argrest, "d") == 0) ftest_domain = argv[i]; | |
1677 | else if (Ustrcmp(argrest, "l") == 0) ftest_localpart = argv[i]; | |
1678 | else if (Ustrcmp(argrest, "p") == 0) ftest_prefix = argv[i]; | |
1679 | else if (Ustrcmp(argrest, "s") == 0) ftest_suffix = argv[i]; | |
1680 | else { badarg = TRUE; break; } | |
1681 | } | |
1682 | } | |
1683 | ||
1684 | /* -bh: Host checking - an IP address must follow. */ | |
1685 | ||
1686 | else if (Ustrcmp(argrest, "h") == 0 || Ustrcmp(argrest, "hc") == 0) | |
1687 | { | |
1688 | if (++i >= argc) { badarg = TRUE; break; } | |
1689 | sender_host_address = argv[i]; | |
1690 | host_checking = checking = log_testing_mode = TRUE; | |
1691 | host_checking_callout = argrest[1] == 'c'; | |
1692 | } | |
1693 | ||
1694 | /* -bi: This option is used by sendmail to initialize *the* alias file, | |
1695 | though it has the -oA option to specify a different file. Exim has no | |
1696 | concept of *the* alias file, but since Sun's YP make script calls | |
1697 | sendmail this way, some support must be provided. */ | |
1698 | ||
1699 | else if (Ustrcmp(argrest, "i") == 0) bi_option = TRUE; | |
1700 | ||
1701 | /* -bm: Accept and deliver message - the default option. Reinstate | |
1702 | receiving_message, which got turned off for all -b options. */ | |
1703 | ||
1704 | else if (Ustrcmp(argrest, "m") == 0) receiving_message = TRUE; | |
1705 | ||
1706 | /* -bnq: For locally originating messages, do not qualify unqualified | |
1707 | addresses. In the envelope, this causes errors; in header lines they | |
1708 | just get left. */ | |
1709 | ||
1710 | else if (Ustrcmp(argrest, "nq") == 0) | |
1711 | { | |
1712 | allow_unqualified_sender = FALSE; | |
1713 | allow_unqualified_recipient = FALSE; | |
1714 | } | |
1715 | ||
1716 | /* -bpxx: List the contents of the mail queue, in various forms. If | |
1717 | the option is -bpc, just a queue count is needed. Otherwise, if the | |
1718 | first letter after p is r, then order is random. */ | |
1719 | ||
1720 | else if (*argrest == 'p') | |
1721 | { | |
1722 | if (*(++argrest) == 'c') | |
1723 | { | |
1724 | count_queue = TRUE; | |
1725 | if (*(++argrest) != 0) badarg = TRUE; | |
1726 | break; | |
1727 | } | |
1728 | ||
1729 | if (*argrest == 'r') | |
1730 | { | |
1731 | list_queue_option = 8; | |
1732 | argrest++; | |
1733 | } | |
1734 | else list_queue_option = 0; | |
1735 | ||
1736 | list_queue = TRUE; | |
1737 | ||
1738 | /* -bp: List the contents of the mail queue, top-level only */ | |
1739 | ||
1740 | if (*argrest == 0) {} | |
1741 | ||
1742 | /* -bpu: List the contents of the mail queue, top-level undelivered */ | |
1743 | ||
1744 | else if (Ustrcmp(argrest, "u") == 0) list_queue_option += 1; | |
1745 | ||
1746 | /* -bpa: List the contents of the mail queue, including all delivered */ | |
1747 | ||
1748 | else if (Ustrcmp(argrest, "a") == 0) list_queue_option += 2; | |
1749 | ||
1750 | /* Unknown after -bp[r] */ | |
1751 | ||
1752 | else | |
1753 | { | |
1754 | badarg = TRUE; | |
1755 | break; | |
1756 | } | |
1757 | } | |
1758 | ||
1759 | ||
1760 | /* -bP: List the configuration variables given as the address list. | |
1761 | Force -v, so configuration errors get displayed. */ | |
1762 | ||
1763 | else if (Ustrcmp(argrest, "P") == 0) | |
1764 | { | |
1765 | list_options = TRUE; | |
1766 | debug_selector |= D_v; | |
1767 | debug_file = stderr; | |
1768 | } | |
1769 | ||
1770 | /* -brt: Test retry configuration lookup */ | |
1771 | ||
1772 | else if (Ustrcmp(argrest, "rt") == 0) | |
1773 | { | |
1774 | test_retry_arg = i + 1; | |
1775 | goto END_ARG; | |
1776 | } | |
1777 | ||
1778 | /* -brw: Test rewrite configuration */ | |
1779 | ||
1780 | else if (Ustrcmp(argrest, "rw") == 0) | |
1781 | { | |
1782 | test_rewrite_arg = i + 1; | |
1783 | goto END_ARG; | |
1784 | } | |
1785 | ||
1786 | /* -bS: Read SMTP commands on standard input, but produce no replies - | |
1787 | all errors are reported by sending messages. */ | |
1788 | ||
1789 | else if (Ustrcmp(argrest, "S") == 0) | |
1790 | smtp_input = smtp_batched_input = receiving_message = TRUE; | |
1791 | ||
1792 | /* -bs: Read SMTP commands on standard input and produce SMTP replies | |
1793 | on standard output. */ | |
1794 | ||
1795 | else if (Ustrcmp(argrest, "s") == 0) smtp_input = receiving_message = TRUE; | |
1796 | ||
1797 | /* -bt: address testing mode */ | |
1798 | ||
1799 | else if (Ustrcmp(argrest, "t") == 0) | |
1800 | address_test_mode = checking = log_testing_mode = TRUE; | |
1801 | ||
1802 | /* -bv: verify addresses */ | |
1803 | ||
1804 | else if (Ustrcmp(argrest, "v") == 0) | |
1805 | verify_address_mode = checking = log_testing_mode = TRUE; | |
1806 | ||
1807 | /* -bvs: verify sender addresses */ | |
1808 | ||
1809 | else if (Ustrcmp(argrest, "vs") == 0) | |
1810 | { | |
1811 | verify_address_mode = checking = log_testing_mode = TRUE; | |
1812 | verify_as_sender = TRUE; | |
1813 | } | |
1814 | ||
1815 | /* -bV: Print version string and support details */ | |
1816 | ||
1817 | else if (Ustrcmp(argrest, "V") == 0) | |
1818 | { | |
1819 | printf("Exim version %s #%s built %s\n", version_string, | |
1820 | version_cnumber, version_date); | |
1821 | printf("%s\n", CS version_copyright); | |
1822 | version_printed = TRUE; | |
1823 | show_whats_supported(stdout); | |
1824 | } | |
1825 | ||
1826 | else badarg = TRUE; | |
1827 | break; | |
1828 | ||
1829 | ||
1830 | /* -C: change configuration file list; ignore if it isn't really | |
1831 | a change! Enforce a prefix check if required. */ | |
1832 | ||
1833 | case 'C': | |
1834 | if (*argrest == 0) | |
1835 | { | |
1836 | if(++i < argc) argrest = argv[i]; else | |
1837 | { badarg = TRUE; break; } | |
1838 | } | |
1839 | if (Ustrcmp(config_main_filelist, argrest) != 0) | |
1840 | { | |
1841 | #ifdef ALT_CONFIG_PREFIX | |
1842 | int sep = 0; | |
1843 | int len = Ustrlen(ALT_CONFIG_PREFIX); | |
1844 | uschar *list = argrest; | |
1845 | uschar *filename; | |
1846 | while((filename = string_nextinlist(&list, &sep, big_buffer, | |
1847 | big_buffer_size)) != NULL) | |
1848 | { | |
1849 | if ((Ustrlen(filename) < len || | |
1850 | Ustrncmp(filename, ALT_CONFIG_PREFIX, len) != 0 || | |
1851 | Ustrstr(filename, "/../") != NULL) && | |
1852 | (Ustrcmp(filename, "/dev/null") != 0 || real_uid != root_uid)) | |
1853 | { | |
1854 | fprintf(stderr, "-C Permission denied\n"); | |
1855 | exit(EXIT_FAILURE); | |
1856 | } | |
1857 | } | |
1858 | #endif | |
1859 | ||
1860 | config_main_filelist = argrest; | |
1861 | config_changed = TRUE; | |
1862 | } | |
1863 | break; | |
1864 | ||
1865 | ||
1866 | /* -D: set up a macro definition */ | |
1867 | ||
1868 | case 'D': | |
1869 | #ifdef DISABLE_D_OPTION | |
1870 | fprintf(stderr, "exim: -D is not available in this Exim binary\n"); | |
1871 | exit(EXIT_FAILURE); | |
1872 | #else | |
1873 | { | |
1874 | int ptr = 0; | |
1875 | macro_item *mlast = NULL; | |
1876 | macro_item *m; | |
1877 | uschar name[24]; | |
1878 | uschar *s = argrest; | |
1879 | ||
1880 | while (isspace(*s)) s++; | |
1881 | ||
1882 | if (*s < 'A' || *s > 'Z') | |
1883 | { | |
1884 | fprintf(stderr, "exim: macro name set by -D must start with " | |
1885 | "an upper case letter\n"); | |
1886 | exit(EXIT_FAILURE); | |
1887 | } | |
1888 | ||
1889 | while (isalnum(*s) || *s == '_') | |
1890 | { | |
1891 | if (ptr < sizeof(name)-1) name[ptr++] = *s; | |
1892 | s++; | |
1893 | } | |
1894 | name[ptr] = 0; | |
1895 | if (ptr == 0) { badarg = TRUE; break; } | |
1896 | while (isspace(*s)) s++; | |
1897 | if (*s != 0) | |
1898 | { | |
1899 | if (*s++ != '=') { badarg = TRUE; break; } | |
1900 | while (isspace(*s)) s++; | |
1901 | } | |
1902 | ||
1903 | for (m = macros; m != NULL; m = m->next) | |
1904 | { | |
1905 | if (Ustrcmp(m->name, name) == 0) | |
1906 | { | |
1907 | fprintf(stderr, "exim: duplicated -D in command line\n"); | |
1908 | exit(EXIT_FAILURE); | |
1909 | } | |
1910 | mlast = m; | |
1911 | } | |
1912 | ||
1913 | m = store_get(sizeof(macro_item) + Ustrlen(name)); | |
1914 | m->next = NULL; | |
1915 | m->command_line = TRUE; | |
1916 | if (mlast == NULL) macros = m; else mlast->next = m; | |
1917 | Ustrcpy(m->name, name); | |
1918 | m->replacement = string_copy(s); | |
1919 | ||
1920 | if (clmacro_count >= MAX_CLMACROS) | |
1921 | { | |
1922 | fprintf(stderr, "exim: too many -D options on command line\n"); | |
1923 | exit(EXIT_FAILURE); | |
1924 | } | |
1925 | clmacros[clmacro_count++] = string_sprintf("-D%s=%s", m->name, | |
1926 | m->replacement); | |
1927 | } | |
1928 | #endif | |
1929 | break; | |
1930 | ||
1931 | /* -d: Set debug level (see also -v below) or set the drop_cr option. | |
8e669ac1 | 1932 | The latter is now a no-op, retained for compatibility only. If -dd is used, |
3d235903 | 1933 | debugging subprocesses of the daemon is disabled. */ |
059ec3d9 PH |
1934 | |
1935 | case 'd': | |
1936 | if (Ustrcmp(argrest, "ropcr") == 0) | |
1937 | { | |
1938 | /* drop_cr = TRUE; */ | |
1939 | } | |
1940 | ||
1941 | /* Use an intermediate variable so that we don't set debugging while | |
1942 | decoding the debugging bits. */ | |
1943 | ||
1944 | else | |
1945 | { | |
1946 | unsigned int selector = D_default; | |
1947 | debug_selector = 0; | |
1948 | debug_file = NULL; | |
3d235903 PH |
1949 | if (*argrest == 'd') |
1950 | { | |
1951 | debug_daemon = TRUE; | |
1952 | argrest++; | |
1953 | } | |
059ec3d9 | 1954 | if (*argrest != 0) |
1fe64dcc | 1955 | decode_bits(&selector, NULL, D_memory, 0, argrest, debug_options, |
059ec3d9 PH |
1956 | debug_options_count, US"debug"); |
1957 | debug_selector = selector; | |
1958 | } | |
1959 | break; | |
1960 | ||
1961 | ||
1962 | /* -E: This is a local error message. This option is not intended for | |
1963 | external use at all, but is not restricted to trusted callers because it | |
1964 | does no harm (just suppresses certain error messages) and if Exim is run | |
1965 | not setuid root it won't always be trusted when it generates error | |
1966 | messages using this option. If there is a message id following -E, point | |
1967 | message_reference at it, for logging. */ | |
1968 | ||
1969 | case 'E': | |
1970 | local_error_message = TRUE; | |
1971 | if (mac_ismsgid(argrest)) message_reference = argrest; | |
1972 | break; | |
1973 | ||
1974 | ||
1975 | /* -ex: The vacation program calls sendmail with the undocumented "-eq" | |
1976 | option, so it looks as if historically the -oex options are also callable | |
1977 | without the leading -o. So we have to accept them. Before the switch, | |
1978 | anything starting -oe has been converted to -e. Exim does not support all | |
1979 | of the sendmail error options. */ | |
1980 | ||
1981 | case 'e': | |
1982 | if (Ustrcmp(argrest, "e") == 0) | |
1983 | { | |
1984 | arg_error_handling = ERRORS_SENDER; | |
1985 | errors_sender_rc = EXIT_SUCCESS; | |
1986 | } | |
1987 | else if (Ustrcmp(argrest, "m") == 0) arg_error_handling = ERRORS_SENDER; | |
1988 | else if (Ustrcmp(argrest, "p") == 0) arg_error_handling = ERRORS_STDERR; | |
1989 | else if (Ustrcmp(argrest, "q") == 0) arg_error_handling = ERRORS_STDERR; | |
1990 | else if (Ustrcmp(argrest, "w") == 0) arg_error_handling = ERRORS_SENDER; | |
1991 | else badarg = TRUE; | |
1992 | break; | |
1993 | ||
1994 | ||
1995 | /* -F: Set sender's full name, used instead of the gecos entry from | |
1996 | the password file. Since users can usually alter their gecos entries, | |
1997 | there's no security involved in using this instead. The data can follow | |
1998 | the -F or be in the next argument. */ | |
1999 | ||
2000 | case 'F': | |
2001 | if (*argrest == 0) | |
2002 | { | |
2003 | if(++i < argc) argrest = argv[i]; else | |
2004 | { badarg = TRUE; break; } | |
2005 | } | |
2006 | originator_name = argrest; | |
2fe1a124 | 2007 | sender_name_forced = TRUE; |
059ec3d9 PH |
2008 | break; |
2009 | ||
2010 | ||
2011 | /* -f: Set sender's address - this value is only actually used if Exim is | |
2012 | run by a trusted user, or if untrusted_set_sender is set and matches the | |
2013 | address, except that the null address can always be set by any user. The | |
2014 | test for this happens later, when the value given here is ignored when not | |
2015 | permitted. For an untrusted user, the actual sender is still put in Sender: | |
2016 | if it doesn't match the From: header (unless no_local_from_check is set). | |
2017 | The data can follow the -f or be in the next argument. The -r switch is an | |
2018 | obsolete form of -f but since there appear to be programs out there that | |
2019 | use anything that sendmail has ever supported, better accept it - the | |
2020 | synonymizing is done before the switch above. | |
2021 | ||
2022 | At this stage, we must allow domain literal addresses, because we don't | |
2023 | know what the setting of allow_domain_literals is yet. Ditto for trailing | |
2024 | dots and strip_trailing_dot. */ | |
2025 | ||
2026 | case 'f': | |
2027 | { | |
2028 | int start, end; | |
2029 | uschar *errmess; | |
2030 | if (*argrest == 0) | |
2031 | { | |
2032 | if (i+1 < argc) argrest = argv[++i]; else | |
2033 | { badarg = TRUE; break; } | |
2034 | } | |
2035 | if (*argrest == 0) | |
2036 | { | |
2037 | sender_address = string_sprintf(""); /* Ensure writeable memory */ | |
2038 | } | |
2039 | else | |
2040 | { | |
2041 | uschar *temp = argrest + Ustrlen(argrest) - 1; | |
2042 | while (temp >= argrest && isspace(*temp)) temp--; | |
2043 | if (temp >= argrest && *temp == '.') f_end_dot = TRUE; | |
2044 | allow_domain_literals = TRUE; | |
2045 | strip_trailing_dot = TRUE; | |
2046 | sender_address = parse_extract_address(argrest, &errmess, &start, &end, | |
2047 | &sender_address_domain, TRUE); | |
2048 | allow_domain_literals = FALSE; | |
2049 | strip_trailing_dot = FALSE; | |
2050 | if (sender_address == NULL) | |
2051 | { | |
2052 | fprintf(stderr, "exim: bad -f address \"%s\": %s\n", argrest, errmess); | |
2053 | return EXIT_FAILURE; | |
2054 | } | |
2055 | } | |
2056 | sender_address_forced = TRUE; | |
2057 | } | |
2058 | break; | |
2059 | ||
2060 | /* This is some Sendmail thing which can be ignored */ | |
2061 | ||
2062 | case 'G': | |
2063 | break; | |
2064 | ||
2065 | /* -h: Set the hop count for an incoming message. Exim does not currently | |
2066 | support this; it always computes it by counting the Received: headers. | |
2067 | To put it in will require a change to the spool header file format. */ | |
2068 | ||
2069 | case 'h': | |
2070 | if (*argrest == 0) | |
2071 | { | |
2072 | if(++i < argc) argrest = argv[i]; else | |
2073 | { badarg = TRUE; break; } | |
2074 | } | |
2075 | if (!isdigit(*argrest)) badarg = TRUE; | |
2076 | break; | |
2077 | ||
2078 | ||
2079 | /* -i: Set flag so dot doesn't end non-SMTP input (same as -oi, seems | |
2080 | not to be documented for sendmail but mailx (at least) uses it) */ | |
2081 | ||
2082 | case 'i': | |
2083 | if (*argrest == 0) dot_ends = FALSE; else badarg = TRUE; | |
2084 | break; | |
2085 | ||
2086 | ||
2087 | case 'M': | |
2088 | receiving_message = FALSE; | |
2089 | ||
2090 | /* -MC: continue delivery of another message via an existing open | |
2091 | file descriptor. This option is used for an internal call by the | |
2092 | smtp transport when there is a pending message waiting to go to an | |
2093 | address to which it has got a connection. Five subsequent arguments are | |
2094 | required: transport name, host name, IP address, sequence number, and | |
2095 | message_id. Transports may decline to create new processes if the sequence | |
2096 | number gets too big. The channel is stdin. This (-MC) must be the last | |
2097 | argument. There's a subsequent check that the real-uid is privileged. | |
2098 | ||
2099 | If we are running in the test harness. delay for a bit, to let the process | |
2100 | that set this one up complete. This makes for repeatability of the logging, | |
2101 | etc. output. */ | |
2102 | ||
2103 | if (Ustrcmp(argrest, "C") == 0) | |
2104 | { | |
2105 | if (argc != i + 6) | |
2106 | { | |
2107 | fprintf(stderr, "exim: too many or too few arguments after -MC\n"); | |
2108 | return EXIT_FAILURE; | |
2109 | } | |
2110 | ||
2111 | if (msg_action_arg >= 0) | |
2112 | { | |
2113 | fprintf(stderr, "exim: incompatible arguments\n"); | |
2114 | return EXIT_FAILURE; | |
2115 | } | |
2116 | ||
2117 | continue_transport = argv[++i]; | |
2118 | continue_hostname = argv[++i]; | |
2119 | continue_host_address = argv[++i]; | |
2120 | continue_sequence = Uatoi(argv[++i]); | |
2121 | msg_action = MSG_DELIVER; | |
2122 | msg_action_arg = ++i; | |
2123 | forced_delivery = TRUE; | |
2124 | queue_run_pid = passed_qr_pid; | |
2125 | queue_run_pipe = passed_qr_pipe; | |
2126 | ||
2127 | if (!mac_ismsgid(argv[i])) | |
2128 | { | |
2129 | fprintf(stderr, "exim: malformed message id %s after -MC option\n", | |
2130 | argv[i]); | |
2131 | return EXIT_FAILURE; | |
2132 | } | |
2133 | ||
2134 | if (running_in_test_harness) millisleep(500); | |
2135 | break; | |
2136 | } | |
2137 | ||
2138 | /* -MCA: set the smtp_authenticated flag; this is useful only when it | |
2139 | precedes -MC (see above). The flag indicates that the host to which | |
2140 | Exim is connected has accepted an AUTH sequence. */ | |
2141 | ||
2142 | else if (Ustrcmp(argrest, "CA") == 0) | |
2143 | { | |
2144 | smtp_authenticated = TRUE; | |
2145 | break; | |
2146 | } | |
2147 | ||
2148 | /* -MCP: set the smtp_use_pipelining flag; this is useful only when | |
2149 | it preceded -MC (see above) */ | |
2150 | ||
2151 | else if (Ustrcmp(argrest, "CP") == 0) | |
2152 | { | |
2153 | smtp_use_pipelining = TRUE; | |
2154 | break; | |
2155 | } | |
2156 | ||
2157 | /* -MCQ: pass on the pid of the queue-running process that started | |
2158 | this chain of deliveries and the fd of its synchronizing pipe; this | |
2159 | is useful only when it precedes -MC (see above) */ | |
2160 | ||
2161 | else if (Ustrcmp(argrest, "CQ") == 0) | |
2162 | { | |
2163 | if(++i < argc) passed_qr_pid = (pid_t)(Uatol(argv[i])); | |
2164 | else badarg = TRUE; | |
2165 | if(++i < argc) passed_qr_pipe = (int)(Uatol(argv[i])); | |
2166 | else badarg = TRUE; | |
2167 | break; | |
2168 | } | |
2169 | ||
2170 | /* -MCS: set the smtp_use_size flag; this is useful only when it | |
2171 | precedes -MC (see above) */ | |
2172 | ||
2173 | else if (Ustrcmp(argrest, "CS") == 0) | |
2174 | { | |
2175 | smtp_use_size = TRUE; | |
2176 | break; | |
2177 | } | |
2178 | ||
2179 | /* -MCT: set the tls_offered flag; this is useful only when it | |
2180 | precedes -MC (see above). The flag indicates that the host to which | |
2181 | Exim is connected has offered TLS support. */ | |
2182 | ||
2183 | #ifdef SUPPORT_TLS | |
2184 | else if (Ustrcmp(argrest, "CT") == 0) | |
2185 | { | |
2186 | tls_offered = TRUE; | |
2187 | break; | |
2188 | } | |
2189 | #endif | |
2190 | ||
2191 | /* -M[x]: various operations on the following list of message ids: | |
2192 | -M deliver the messages, ignoring next retry times and thawing | |
2193 | -Mc deliver the messages, checking next retry times, no thawing | |
2194 | -Mf freeze the messages | |
2195 | -Mg give up on the messages | |
2196 | -Mt thaw the messages | |
2197 | -Mrm remove the messages | |
2198 | In the above cases, this must be the last option. There are also the | |
2199 | following options which are followed by a single message id, and which | |
2200 | act on that message. Some of them use the "recipient" addresses as well. | |
2201 | -Mar add recipient(s) | |
2202 | -Mmad mark all recipients delivered | |
2203 | -Mmd mark recipients(s) delivered | |
2204 | -Mes edit sender | |
2205 | -Mvb show body | |
2206 | -Mvh show header | |
2207 | -Mvl show log | |
2208 | */ | |
2209 | ||
2210 | else if (*argrest == 0) | |
2211 | { | |
2212 | msg_action = MSG_DELIVER; | |
2213 | forced_delivery = deliver_force_thaw = TRUE; | |
2214 | } | |
2215 | else if (Ustrcmp(argrest, "ar") == 0) | |
2216 | { | |
2217 | msg_action = MSG_ADD_RECIPIENT; | |
2218 | one_msg_action = TRUE; | |
2219 | } | |
2220 | else if (Ustrcmp(argrest, "c") == 0) msg_action = MSG_DELIVER; | |
2221 | else if (Ustrcmp(argrest, "es") == 0) | |
2222 | { | |
2223 | msg_action = MSG_EDIT_SENDER; | |
2224 | one_msg_action = TRUE; | |
2225 | } | |
2226 | else if (Ustrcmp(argrest, "f") == 0) msg_action = MSG_FREEZE; | |
2227 | else if (Ustrcmp(argrest, "g") == 0) | |
2228 | { | |
2229 | msg_action = MSG_DELIVER; | |
2230 | deliver_give_up = TRUE; | |
2231 | } | |
2232 | else if (Ustrcmp(argrest, "mad") == 0) | |
2233 | { | |
2234 | msg_action = MSG_MARK_ALL_DELIVERED; | |
2235 | } | |
2236 | else if (Ustrcmp(argrest, "md") == 0) | |
2237 | { | |
2238 | msg_action = MSG_MARK_DELIVERED; | |
2239 | one_msg_action = TRUE; | |
2240 | } | |
2241 | else if (Ustrcmp(argrest, "rm") == 0) msg_action = MSG_REMOVE; | |
2242 | else if (Ustrcmp(argrest, "t") == 0) msg_action = MSG_THAW; | |
2243 | else if (Ustrcmp(argrest, "vb") == 0) | |
2244 | { | |
2245 | msg_action = MSG_SHOW_BODY; | |
2246 | one_msg_action = TRUE; | |
2247 | } | |
2248 | else if (Ustrcmp(argrest, "vh") == 0) | |
2249 | { | |
2250 | msg_action = MSG_SHOW_HEADER; | |
2251 | one_msg_action = TRUE; | |
2252 | } | |
2253 | else if (Ustrcmp(argrest, "vl") == 0) | |
2254 | { | |
2255 | msg_action = MSG_SHOW_LOG; | |
2256 | one_msg_action = TRUE; | |
2257 | } | |
2258 | else { badarg = TRUE; break; } | |
2259 | ||
2260 | /* All the -Mxx options require at least one message id. */ | |
2261 | ||
2262 | msg_action_arg = i + 1; | |
2263 | if (msg_action_arg >= argc) | |
2264 | { | |
2265 | fprintf(stderr, "exim: no message ids given after %s option\n", arg); | |
2266 | return EXIT_FAILURE; | |
2267 | } | |
2268 | ||
2269 | /* Some require only message ids to follow */ | |
2270 | ||
2271 | if (!one_msg_action) | |
2272 | { | |
2273 | int j; | |
2274 | for (j = msg_action_arg; j < argc; j++) if (!mac_ismsgid(argv[j])) | |
2275 | { | |
2276 | fprintf(stderr, "exim: malformed message id %s after %s option\n", | |
2277 | argv[j], arg); | |
2278 | return EXIT_FAILURE; | |
2279 | } | |
2280 | goto END_ARG; /* Remaining args are ids */ | |
2281 | } | |
2282 | ||
2283 | /* Others require only one message id, possibly followed by addresses, | |
2284 | which will be handled as normal arguments. */ | |
2285 | ||
2286 | else | |
2287 | { | |
2288 | if (!mac_ismsgid(argv[msg_action_arg])) | |
2289 | { | |
2290 | fprintf(stderr, "exim: malformed message id %s after %s option\n", | |
2291 | argv[msg_action_arg], arg); | |
2292 | return EXIT_FAILURE; | |
2293 | } | |
2294 | i++; | |
2295 | } | |
2296 | break; | |
2297 | ||
2298 | ||
2299 | /* Some programs seem to call the -om option without the leading o; | |
2300 | for sendmail it askes for "me too". Exim always does this. */ | |
2301 | ||
2302 | case 'm': | |
2303 | if (*argrest != 0) badarg = TRUE; | |
2304 | break; | |
2305 | ||
2306 | ||
2307 | /* -N: don't do delivery - a debugging option that stops transports doing | |
2308 | their thing. It implies debugging at the D_v level. */ | |
2309 | ||
2310 | case 'N': | |
2311 | if (*argrest == 0) | |
2312 | { | |
2313 | dont_deliver = TRUE; | |
2314 | debug_selector |= D_v; | |
2315 | debug_file = stderr; | |
2316 | } | |
2317 | else badarg = TRUE; | |
2318 | break; | |
2319 | ||
2320 | ||
2321 | /* -n: This means "don't alias" in sendmail, apparently. Just ignore | |
2322 | it. */ | |
2323 | ||
2324 | case 'n': | |
2325 | break; | |
2326 | ||
2327 | /* -O: Just ignore it. In sendmail, apparently -O option=value means set | |
2328 | option to the specified value. This form uses long names. We need to handle | |
2329 | -O option=value and -Ooption=value. */ | |
2330 | ||
2331 | case 'O': | |
2332 | if (*argrest == 0) | |
2333 | { | |
2334 | if (++i >= argc) | |
2335 | { | |
2336 | fprintf(stderr, "exim: string expected after -O\n"); | |
2337 | exit(EXIT_FAILURE); | |
2338 | } | |
2339 | } | |
2340 | break; | |
2341 | ||
2342 | case 'o': | |
2343 | ||
2344 | /* -oA: Set an argument for the bi command (sendmail's "alternate alias | |
2345 | file" option). */ | |
2346 | ||
2347 | if (*argrest == 'A') | |
2348 | { | |
2349 | alias_arg = argrest + 1; | |
2350 | if (alias_arg[0] == 0) | |
2351 | { | |
2352 | if (i+1 < argc) alias_arg = argv[++i]; else | |
2353 | { | |
2354 | fprintf(stderr, "exim: string expected after -oA\n"); | |
2355 | exit(EXIT_FAILURE); | |
2356 | } | |
2357 | } | |
2358 | } | |
2359 | ||
2360 | /* -oB: Set a connection message max value for remote deliveries */ | |
2361 | ||
2362 | else if (*argrest == 'B') | |
2363 | { | |
2364 | uschar *p = argrest + 1; | |
2365 | if (p[0] == 0) | |
2366 | { | |
2367 | if (i+1 < argc && isdigit((argv[i+1][0]))) p = argv[++i]; else | |
2368 | { | |
2369 | connection_max_messages = 1; | |
2370 | p = NULL; | |
2371 | } | |
2372 | } | |
2373 | ||
2374 | if (p != NULL) | |
2375 | { | |
2376 | if (!isdigit(*p)) | |
2377 | { | |
2378 | fprintf(stderr, "exim: number expected after -oB\n"); | |
2379 | exit(EXIT_FAILURE); | |
2380 | } | |
2381 | connection_max_messages = Uatoi(p); | |
2382 | } | |
2383 | } | |
2384 | ||
2385 | /* -odb: background delivery */ | |
2386 | ||
2387 | else if (Ustrcmp(argrest, "db") == 0) | |
2388 | { | |
2389 | synchronous_delivery = FALSE; | |
2390 | arg_queue_only = FALSE; | |
2391 | queue_only_set = TRUE; | |
2392 | } | |
2393 | ||
2394 | /* -odf: foreground delivery (smail-compatible option); same effect as | |
2395 | -odi: interactive (synchronous) delivery (sendmail-compatible option) | |
2396 | */ | |
2397 | ||
2398 | else if (Ustrcmp(argrest, "df") == 0 || Ustrcmp(argrest, "di") == 0) | |
2399 | { | |
2400 | synchronous_delivery = TRUE; | |
2401 | arg_queue_only = FALSE; | |
2402 | queue_only_set = TRUE; | |
2403 | } | |
2404 | ||
2405 | /* -odq: queue only */ | |
2406 | ||
2407 | else if (Ustrcmp(argrest, "dq") == 0) | |
2408 | { | |
2409 | synchronous_delivery = FALSE; | |
2410 | arg_queue_only = TRUE; | |
2411 | queue_only_set = TRUE; | |
2412 | } | |
2413 | ||
2414 | /* -odqs: queue SMTP only - do local deliveries and remote routing, | |
2415 | but no remote delivery */ | |
2416 | ||
2417 | else if (Ustrcmp(argrest, "dqs") == 0) | |
2418 | { | |
2419 | queue_smtp = TRUE; | |
2420 | arg_queue_only = FALSE; | |
2421 | queue_only_set = TRUE; | |
2422 | } | |
2423 | ||
2424 | /* -oex: Sendmail error flags. As these are also accepted without the | |
2425 | leading -o prefix, for compatibility with vacation and other callers, | |
2426 | they are handled with -e above. */ | |
2427 | ||
2428 | /* -oi: Set flag so dot doesn't end non-SMTP input (same as -i) | |
2429 | -oitrue: Another sendmail syntax for the same */ | |
2430 | ||
2431 | else if (Ustrcmp(argrest, "i") == 0 || | |
2432 | Ustrcmp(argrest, "itrue") == 0) | |
2433 | dot_ends = FALSE; | |
2434 | ||
2435 | /* -oM*: Set various characteristics for an incoming message; actually | |
2436 | acted on for trusted callers only. */ | |
2437 | ||
2438 | else if (*argrest == 'M') | |
2439 | { | |
2440 | if (i+1 >= argc) | |
2441 | { | |
2442 | fprintf(stderr, "exim: data expected after -o%s\n", argrest); | |
2443 | exit(EXIT_FAILURE); | |
2444 | } | |
2445 | ||
2446 | /* -oMa: Set sender host address */ | |
2447 | ||
2448 | if (Ustrcmp(argrest, "Ma") == 0) sender_host_address = argv[++i]; | |
2449 | ||
2450 | /* -oMaa: Set authenticator name */ | |
2451 | ||
2452 | else if (Ustrcmp(argrest, "Maa") == 0) | |
2453 | sender_host_authenticated = argv[++i]; | |
2454 | ||
2455 | /* -oMas: setting authenticated sender */ | |
2456 | ||
2457 | else if (Ustrcmp(argrest, "Mas") == 0) authenticated_sender = argv[++i]; | |
2458 | ||
2459 | /* -oMai: setting authenticated id */ | |
2460 | ||
2461 | else if (Ustrcmp(argrest, "Mai") == 0) authenticated_id = argv[++i]; | |
2462 | ||
2463 | /* -oMi: Set incoming interface address */ | |
2464 | ||
2465 | else if (Ustrcmp(argrest, "Mi") == 0) interface_address = argv[++i]; | |
2466 | ||
2467 | /* -oMr: Received protocol */ | |
2468 | ||
2469 | else if (Ustrcmp(argrest, "Mr") == 0) received_protocol = argv[++i]; | |
2470 | ||
2471 | /* -oMs: Set sender host name */ | |
2472 | ||
2473 | else if (Ustrcmp(argrest, "Ms") == 0) sender_host_name = argv[++i]; | |
2474 | ||
2475 | /* -oMt: Set sender ident */ | |
2476 | ||
2477 | else if (Ustrcmp(argrest, "Mt") == 0) sender_ident = argv[++i]; | |
2478 | ||
2479 | /* Else a bad argument */ | |
2480 | ||
2481 | else | |
2482 | { | |
2483 | badarg = TRUE; | |
2484 | break; | |
2485 | } | |
2486 | } | |
2487 | ||
2488 | /* -om: Me-too flag for aliases. Exim always does this. Some programs | |
2489 | seem to call this as -m (undocumented), so that is also accepted (see | |
2490 | above). */ | |
2491 | ||
2492 | else if (Ustrcmp(argrest, "m") == 0) {} | |
2493 | ||
2494 | /* -oo: An ancient flag for old-style addresses which still seems to | |
2495 | crop up in some calls (see in SCO). */ | |
2496 | ||
2497 | else if (Ustrcmp(argrest, "o") == 0) {} | |
2498 | ||
2499 | /* -oP <name>: set pid file path for daemon */ | |
2500 | ||
2501 | else if (Ustrcmp(argrest, "P") == 0) | |
2502 | override_pid_file_path = argv[++i]; | |
2503 | ||
2504 | /* -or <n>: set timeout for non-SMTP acceptance | |
2505 | -os <n>: set timeout for SMTP acceptance */ | |
2506 | ||
2507 | else if (*argrest == 'r' || *argrest == 's') | |
2508 | { | |
2509 | int *tp = (*argrest == 'r')? | |
2510 | &arg_receive_timeout : &arg_smtp_receive_timeout; | |
2511 | if (argrest[1] == 0) | |
2512 | { | |
2513 | if (i+1 < argc) *tp= readconf_readtime(argv[++i], 0, FALSE); | |
2514 | } | |
2515 | else *tp = readconf_readtime(argrest + 1, 0, FALSE); | |
2516 | if (*tp < 0) | |
2517 | { | |
2518 | fprintf(stderr, "exim: bad time value %s: abandoned\n", argv[i]); | |
2519 | exit(EXIT_FAILURE); | |
2520 | } | |
2521 | } | |
2522 | ||
2523 | /* -oX <list>: Override local_interfaces and/or default daemon ports */ | |
2524 | ||
2525 | else if (Ustrcmp(argrest, "X") == 0) | |
2526 | override_local_interfaces = argv[++i]; | |
2527 | ||
2528 | /* Unknown -o argument */ | |
2529 | ||
2530 | else badarg = TRUE; | |
2531 | break; | |
2532 | ||
2533 | ||
2534 | /* -ps: force Perl startup; -pd force delayed Perl startup */ | |
2535 | ||
2536 | case 'p': | |
2537 | #ifdef EXIM_PERL | |
2538 | if (*argrest == 's' && argrest[1] == 0) | |
2539 | { | |
2540 | perl_start_option = 1; | |
2541 | break; | |
2542 | } | |
2543 | if (*argrest == 'd' && argrest[1] == 0) | |
2544 | { | |
2545 | perl_start_option = -1; | |
2546 | break; | |
2547 | } | |
2548 | #endif | |
2549 | ||
2550 | /* -panythingelse is taken as the Sendmail-compatible argument -prval:sval, | |
2551 | which sets the host protocol and host name */ | |
2552 | ||
2553 | if (*argrest == 0) | |
2554 | { | |
2555 | if (i+1 < argc) argrest = argv[++i]; else | |
2556 | { badarg = TRUE; break; } | |
2557 | } | |
2558 | ||
2559 | if (*argrest != 0) | |
2560 | { | |
2561 | uschar *hn = Ustrchr(argrest, ':'); | |
2562 | if (hn == NULL) | |
2563 | { | |
2564 | received_protocol = argrest; | |
2565 | } | |
2566 | else | |
2567 | { | |
2568 | received_protocol = string_copyn(argrest, hn - argrest); | |
2569 | sender_host_name = hn + 1; | |
2570 | } | |
2571 | } | |
2572 | break; | |
2573 | ||
2574 | ||
2575 | case 'q': | |
2576 | receiving_message = FALSE; | |
2577 | ||
2578 | /* -qq...: Do queue runs in a 2-stage manner */ | |
2579 | ||
2580 | if (*argrest == 'q') | |
2581 | { | |
2582 | queue_2stage = TRUE; | |
2583 | argrest++; | |
2584 | } | |
2585 | ||
2586 | /* -qi...: Do only first (initial) deliveries */ | |
2587 | ||
2588 | if (*argrest == 'i') | |
2589 | { | |
2590 | queue_run_first_delivery = TRUE; | |
2591 | argrest++; | |
2592 | } | |
2593 | ||
2594 | /* -qf...: Run the queue, forcing deliveries | |
2595 | -qff..: Ditto, forcing thawing as well */ | |
2596 | ||
2597 | if (*argrest == 'f') | |
2598 | { | |
2599 | queue_run_force = TRUE; | |
2600 | if (*(++argrest) == 'f') | |
2601 | { | |
2602 | deliver_force_thaw = TRUE; | |
2603 | argrest++; | |
2604 | } | |
2605 | } | |
2606 | ||
2607 | /* -q[f][f]l...: Run the queue only on local deliveries */ | |
2608 | ||
2609 | if (*argrest == 'l') | |
2610 | { | |
2611 | queue_run_local = TRUE; | |
2612 | argrest++; | |
2613 | } | |
2614 | ||
2615 | /* -q[f][f][l]: Run the queue, optionally forced, optionally local only, | |
2616 | optionally starting from a given message id. */ | |
2617 | ||
2618 | if (*argrest == 0 && | |
2619 | (i + 1 >= argc || argv[i+1][0] == '-' || mac_ismsgid(argv[i+1]))) | |
2620 | { | |
2621 | queue_interval = 0; | |
2622 | if (i+1 < argc && mac_ismsgid(argv[i+1])) | |
2623 | start_queue_run_id = argv[++i]; | |
2624 | if (i+1 < argc && mac_ismsgid(argv[i+1])) | |
2625 | stop_queue_run_id = argv[++i]; | |
2626 | } | |
2627 | ||
2628 | /* -q[f][f][l]<n>: Run the queue at regular intervals, optionally forced, | |
2629 | optionally local only. */ | |
2630 | ||
2631 | else | |
2632 | { | |
2633 | if (*argrest != 0) | |
2634 | queue_interval = readconf_readtime(argrest, 0, FALSE); | |
2635 | else | |
2636 | queue_interval = readconf_readtime(argv[++i], 0, FALSE); | |
2637 | if (queue_interval <= 0) | |
2638 | { | |
2639 | fprintf(stderr, "exim: bad time value %s: abandoned\n", argv[i]); | |
2640 | exit(EXIT_FAILURE); | |
2641 | } | |
2642 | } | |
2643 | break; | |
2644 | ||
2645 | ||
2646 | case 'R': /* Synonymous with -qR... */ | |
2647 | receiving_message = FALSE; | |
2648 | ||
2649 | /* -Rf: As -R (below) but force all deliveries, | |
2650 | -Rff: Ditto, but also thaw all frozen messages, | |
2651 | -Rr: String is regex | |
2652 | -Rrf: Regex and force | |
2653 | -Rrff: Regex and force and thaw | |
2654 | ||
2655 | in all cases provided there are no further characters in this | |
2656 | argument. */ | |
2657 | ||
2658 | if (*argrest != 0) | |
2659 | { | |
2660 | int i; | |
2661 | for (i = 0; i < sizeof(rsopts)/sizeof(uschar *); i++) | |
2662 | { | |
2663 | if (Ustrcmp(argrest, rsopts[i]) == 0) | |
2664 | { | |
2665 | if (i != 2) queue_run_force = TRUE; | |
2666 | if (i >= 2) deliver_selectstring_regex = TRUE; | |
2667 | if (i == 1 || i == 4) deliver_force_thaw = TRUE; | |
2668 | argrest += Ustrlen(rsopts[i]); | |
2669 | } | |
2670 | } | |
2671 | } | |
2672 | ||
2673 | /* -R: Set string to match in addresses for forced queue run to | |
2674 | pick out particular messages. */ | |
2675 | ||
2676 | if (*argrest == 0) | |
2677 | { | |
2678 | if (i+1 < argc) deliver_selectstring = argv[++i]; else | |
2679 | { | |
2680 | fprintf(stderr, "exim: string expected after -R\n"); | |
2681 | exit(EXIT_FAILURE); | |
2682 | } | |
2683 | } | |
2684 | else deliver_selectstring = argrest; | |
2685 | if (queue_interval < 0) queue_interval = 0; | |
2686 | break; | |
2687 | ||
2688 | ||
2689 | /* -r: an obsolete synonym for -f (see above) */ | |
2690 | ||
2691 | ||
2692 | /* -S: Like -R but works on sender. */ | |
2693 | ||
2694 | case 'S': /* Synonymous with -qS... */ | |
2695 | receiving_message = FALSE; | |
2696 | ||
2697 | /* -Sf: As -S (below) but force all deliveries, | |
2698 | -Sff: Ditto, but also thaw all frozen messages, | |
2699 | -Sr: String is regex | |
2700 | -Srf: Regex and force | |
2701 | -Srff: Regex and force and thaw | |
2702 | ||
2703 | in all cases provided there are no further characters in this | |
2704 | argument. */ | |
2705 | ||
2706 | if (*argrest != 0) | |
2707 | { | |
2708 | int i; | |
2709 | for (i = 0; i < sizeof(rsopts)/sizeof(uschar *); i++) | |
2710 | { | |
2711 | if (Ustrcmp(argrest, rsopts[i]) == 0) | |
2712 | { | |
2713 | if (i != 2) queue_run_force = TRUE; | |
2714 | if (i >= 2) deliver_selectstring_sender_regex = TRUE; | |
2715 | if (i == 1 || i == 4) deliver_force_thaw = TRUE; | |
2716 | argrest += Ustrlen(rsopts[i]); | |
2717 | } | |
2718 | } | |
2719 | } | |
2720 | ||
2721 | /* -S: Set string to match in addresses for forced queue run to | |
2722 | pick out particular messages. */ | |
2723 | ||
2724 | if (*argrest == 0) | |
2725 | { | |
2726 | if (i+1 < argc) deliver_selectstring_sender = argv[++i]; else | |
2727 | { | |
2728 | fprintf(stderr, "exim: string expected after -S\n"); | |
2729 | exit(EXIT_FAILURE); | |
2730 | } | |
2731 | } | |
2732 | else deliver_selectstring_sender = argrest; | |
2733 | if (queue_interval < 0) queue_interval = 0; | |
2734 | break; | |
2735 | ||
2736 | /* -Tqt is an option that is exclusively for use by the testing suite. | |
2737 | It is not recognized in other circumstances. It allows for the setting up | |
2738 | of explicit "queue times" so that various warning/retry things can be | |
2739 | tested. Otherwise variability of clock ticks etc. cause problems. */ | |
2740 | ||
2741 | case 'T': | |
2742 | if (running_in_test_harness && Ustrcmp(argrest, "qt") == 0) | |
2743 | fudged_queue_times = argv[++i]; | |
2744 | else badarg = TRUE; | |
2745 | break; | |
2746 | ||
2747 | ||
2748 | /* -t: Set flag to extract recipients from body of message. */ | |
2749 | ||
2750 | case 't': | |
2751 | if (*argrest == 0) extract_recipients = TRUE; | |
2752 | ||
2753 | /* -ti: Set flag to extract recipients from body of message, and also | |
2754 | specify that dot does not end the message. */ | |
2755 | ||
2756 | else if (Ustrcmp(argrest, "i") == 0) | |
2757 | { | |
2758 | extract_recipients = TRUE; | |
2759 | dot_ends = FALSE; | |
2760 | } | |
2761 | ||
2762 | /* -tls-on-connect: don't wait for STARTTLS (for old clients) */ | |
2763 | ||
2764 | #ifdef SUPPORT_TLS | |
2765 | else if (Ustrcmp(argrest, "ls-on-connect") == 0) tls_on_connect = TRUE; | |
2766 | #endif | |
2767 | ||
2768 | else badarg = TRUE; | |
2769 | break; | |
2770 | ||
2771 | ||
2772 | /* -U: This means "initial user submission" in sendmail, apparently. The | |
2773 | doc claims that in future sendmail may refuse syntactically invalid | |
2774 | messages instead of fixing them. For the moment, we just ignore it. */ | |
2775 | ||
2776 | case 'U': | |
2777 | break; | |
2778 | ||
2779 | ||
2780 | /* -v: verify things - this is a very low-level debugging */ | |
2781 | ||
2782 | case 'v': | |
2783 | if (*argrest == 0) | |
2784 | { | |
2785 | debug_selector |= D_v; | |
2786 | debug_file = stderr; | |
2787 | } | |
2788 | else badarg = TRUE; | |
2789 | break; | |
2790 | ||
2791 | ||
2792 | /* -x: AIX uses this to indicate some fancy 8-bit character stuff: | |
2793 | ||
2794 | The -x flag tells the sendmail command that mail from a local | |
2795 | mail program has National Language Support (NLS) extended characters | |
2796 | in the body of the mail item. The sendmail command can send mail with | |
2797 | extended NLS characters across networks that normally corrupts these | |
2798 | 8-bit characters. | |
2799 | ||
2800 | As Exim is 8-bit clean, it just ignores this flag. */ | |
2801 | ||
2802 | case 'x': | |
2803 | if (*argrest != 0) badarg = TRUE; | |
2804 | break; | |
2805 | ||
2806 | /* All other initial characters are errors */ | |
2807 | ||
2808 | default: | |
2809 | badarg = TRUE; | |
2810 | break; | |
2811 | } /* End of high-level switch statement */ | |
2812 | ||
2813 | /* Failed to recognize the option, or syntax error */ | |
2814 | ||
2815 | if (badarg) | |
2816 | { | |
2817 | fprintf(stderr, "exim abandoned: unknown, malformed, or incomplete " | |
2818 | "option %s\n", arg); | |
2819 | exit(EXIT_FAILURE); | |
2820 | } | |
2821 | } | |
2822 | ||
2823 | ||
2824 | /* Arguments have been processed. Check for incompatibilities. */ | |
2825 | ||
2826 | END_ARG: | |
2827 | if (( | |
2828 | (smtp_input || extract_recipients || recipients_arg < argc) && | |
2829 | (daemon_listen || queue_interval >= 0 || bi_option || | |
2830 | test_retry_arg >= 0 || test_rewrite_arg >= 0 || | |
f05da2e8 | 2831 | filter_test != FTEST_NONE || (msg_action_arg > 0 && !one_msg_action)) |
059ec3d9 PH |
2832 | ) || |
2833 | ( | |
2834 | msg_action_arg > 0 && | |
2835 | (daemon_listen || queue_interval >= 0 || list_options || checking || | |
2836 | bi_option || test_retry_arg >= 0 || test_rewrite_arg >= 0) | |
2837 | ) || | |
2838 | ( | |
2839 | (daemon_listen || queue_interval >= 0) && | |
2840 | (sender_address != NULL || list_options || list_queue || checking || | |
2841 | bi_option) | |
2842 | ) || | |
2843 | ( | |
2844 | daemon_listen && queue_interval == 0 | |
2845 | ) || | |
2846 | ( | |
2847 | list_options && | |
2848 | (checking || smtp_input || extract_recipients || | |
f05da2e8 | 2849 | filter_test != FTEST_NONE || bi_option) |
059ec3d9 PH |
2850 | ) || |
2851 | ( | |
2852 | verify_address_mode && | |
2853 | (address_test_mode || smtp_input || extract_recipients || | |
f05da2e8 | 2854 | filter_test != FTEST_NONE || bi_option) |
059ec3d9 PH |
2855 | ) || |
2856 | ( | |
2857 | address_test_mode && (smtp_input || extract_recipients || | |
f05da2e8 | 2858 | filter_test != FTEST_NONE || bi_option) |
059ec3d9 PH |
2859 | ) || |
2860 | ( | |
f05da2e8 | 2861 | smtp_input && (sender_address != NULL || filter_test != FTEST_NONE || |
059ec3d9 PH |
2862 | extract_recipients) |
2863 | ) || | |
2864 | ( | |
2865 | deliver_selectstring != NULL && queue_interval < 0 | |
2866 | ) | |
2867 | ) | |
2868 | { | |
2869 | fprintf(stderr, "exim: incompatible command-line options or arguments\n"); | |
2870 | exit(EXIT_FAILURE); | |
2871 | } | |
2872 | ||
2873 | /* If debugging is set up, set the file and the file descriptor to pass on to | |
2874 | child processes. It should, of course, be 2 for stderr. Also, force the daemon | |
2875 | to run in the foreground. */ | |
2876 | ||
2877 | if (debug_selector != 0) | |
2878 | { | |
2879 | debug_file = stderr; | |
2880 | debug_fd = fileno(debug_file); | |
2881 | background_daemon = FALSE; | |
2882 | if (running_in_test_harness) millisleep(100); /* lets caller finish */ | |
2883 | if (debug_selector != D_v) /* -v only doesn't show this */ | |
2884 | { | |
2885 | debug_printf("Exim version %s uid=%ld gid=%ld pid=%d D=%x\n", | |
2886 | version_string, (long int)real_uid, (long int)real_gid, (int)getpid(), | |
2887 | debug_selector); | |
2888 | show_whats_supported(stderr); | |
2889 | } | |
2890 | } | |
2891 | ||
2892 | /* When started with root privilege, ensure that the limits on the number of | |
2893 | open files and the number of processes (where that is accessible) are | |
2894 | sufficiently large, or are unset, in case Exim has been called from an | |
2895 | environment where the limits are screwed down. Not all OS have the ability to | |
2896 | change some of these limits. */ | |
2897 | ||
2898 | if (unprivileged) | |
2899 | { | |
2900 | DEBUG(D_any) debug_print_ids(US"Exim has no root privilege:"); | |
2901 | } | |
2902 | else | |
2903 | { | |
2904 | struct rlimit rlp; | |
2905 | ||
2906 | #ifdef RLIMIT_NOFILE | |
2907 | if (getrlimit(RLIMIT_NOFILE, &rlp) < 0) | |
2908 | { | |
2909 | log_write(0, LOG_MAIN|LOG_PANIC, "getrlimit(RLIMIT_NOFILE) failed: %s", | |
2910 | strerror(errno)); | |
2911 | rlp.rlim_cur = rlp.rlim_max = 0; | |
2912 | } | |
eb2c0248 PH |
2913 | |
2914 | /* I originally chose 1000 as a nice big number that was unlikely to | |
a494b1e1 PH |
2915 | be exceeded. It turns out that some older OS have a fixed upper limit of |
2916 | 256. */ | |
eb2c0248 | 2917 | |
059ec3d9 PH |
2918 | if (rlp.rlim_cur < 1000) |
2919 | { | |
2920 | rlp.rlim_cur = rlp.rlim_max = 1000; | |
2921 | if (setrlimit(RLIMIT_NOFILE, &rlp) < 0) | |
eb2c0248 | 2922 | { |
a494b1e1 PH |
2923 | rlp.rlim_cur = rlp.rlim_max = 256; |
2924 | if (setrlimit(RLIMIT_NOFILE, &rlp) < 0) | |
2925 | log_write(0, LOG_MAIN|LOG_PANIC, "setrlimit(RLIMIT_NOFILE) failed: %s", | |
2926 | strerror(errno)); | |
eb2c0248 | 2927 | } |
059ec3d9 PH |
2928 | } |
2929 | #endif | |
2930 | ||
2931 | #ifdef RLIMIT_NPROC | |
2932 | if (getrlimit(RLIMIT_NPROC, &rlp) < 0) | |
2933 | { | |
2934 | log_write(0, LOG_MAIN|LOG_PANIC, "getrlimit(RLIMIT_NPROC) failed: %s", | |
2935 | strerror(errno)); | |
2936 | rlp.rlim_cur = rlp.rlim_max = 0; | |
2937 | } | |
2938 | ||
2939 | #ifdef RLIM_INFINITY | |
2940 | if (rlp.rlim_cur != RLIM_INFINITY && rlp.rlim_cur < 1000) | |
2941 | { | |
2942 | rlp.rlim_cur = rlp.rlim_max = RLIM_INFINITY; | |
2943 | #else | |
2944 | if (rlp.rlim_cur < 1000) | |
2945 | { | |
2946 | rlp.rlim_cur = rlp.rlim_max = 1000; | |
2947 | #endif | |
2948 | if (setrlimit(RLIMIT_NPROC, &rlp) < 0) | |
2949 | log_write(0, LOG_MAIN|LOG_PANIC, "setrlimit(RLIMIT_NPROC) failed: %s", | |
2950 | strerror(errno)); | |
2951 | } | |
2952 | #endif | |
2953 | } | |
2954 | ||
2955 | /* Exim is normally entered as root (but some special configurations are | |
2956 | possible that don't do this). However, it always spins off sub-processes that | |
2957 | set their uid and gid as required for local delivery. We don't want to pass on | |
2958 | any extra groups that root may belong to, so we want to get rid of them all at | |
2959 | this point. | |
2960 | ||
2961 | We need to obey setgroups() at this stage, before possibly giving up root | |
2962 | privilege for a changed configuration file, but later on we might need to | |
2963 | check on the additional groups for the admin user privilege - can't do that | |
2964 | till after reading the config, which might specify the exim gid. Therefore, | |
2965 | save the group list here first. */ | |
2966 | ||
2967 | group_count = getgroups(NGROUPS_MAX, group_list); | |
2968 | ||
2969 | /* There is a fundamental difference in some BSD systems in the matter of | |
2970 | groups. FreeBSD and BSDI are known to be different; NetBSD and OpenBSD are | |
2971 | known not to be different. On the "different" systems there is a single group | |
2972 | list, and the first entry in it is the current group. On all other versions of | |
2973 | Unix there is a supplementary group list, which is in *addition* to the current | |
2974 | group. Consequently, to get rid of all extraneous groups on a "standard" system | |
2975 | you pass over 0 groups to setgroups(), while on a "different" system you pass | |
2976 | over a single group - the current group, which is always the first group in the | |
2977 | list. Calling setgroups() with zero groups on a "different" system results in | |
2978 | an error return. The following code should cope with both types of system. | |
2979 | ||
2980 | However, if this process isn't running as root, setgroups() can't be used | |
2981 | since you have to be root to run it, even if throwing away groups. Not being | |
2982 | root here happens only in some unusual configurations. We just ignore the | |
2983 | error. */ | |
2984 | ||
2985 | if (setgroups(0, NULL) != 0) | |
2986 | { | |
2987 | if (setgroups(1, group_list) != 0 && !unprivileged) | |
2988 | { | |
2989 | fprintf(stderr, "exim: setgroups() failed: %s\n", strerror(errno)); | |
2990 | exit(EXIT_FAILURE); | |
2991 | } | |
2992 | } | |
2993 | ||
2994 | /* If the configuration file name has been altered by an argument on the | |
2995 | command line (either a new file name or a macro definition) and the caller is | |
2996 | not root or the exim user, or if this is a filter testing run, remove any | |
2997 | setuid privilege the program has, and run as the underlying user. | |
2998 | ||
2999 | If ALT_CONFIG_ROOT_ONLY is defined, the exim user is locked out of this, which | |
3000 | severely restricts the use of -C for some purposes. | |
3001 | ||
3002 | Otherwise, set the real ids to the effective values (should be root unless run | |
3003 | from inetd, which it can either be root or the exim uid, if one is configured). | |
3004 | ||
3005 | There is a private mechanism for bypassing some of this, in order to make it | |
3006 | possible to test lots of configurations automatically, without having either to | |
3007 | recompile each time, or to patch in an actual configuration file name and other | |
3008 | values (such as the path name). If running in the test harness, pretend that | |
3009 | configuration file changes and macro definitions haven't happened. */ | |
3010 | ||
3011 | if (( /* EITHER */ | |
3012 | (config_changed || macros != NULL) && /* Config changed, and */ | |
3013 | real_uid != root_uid && /* Not root, and */ | |
3014 | #ifndef ALT_CONFIG_ROOT_ONLY /* (when not locked out) */ | |
3015 | real_uid != exim_uid && /* Not exim, and */ | |
3016 | #endif | |
3017 | !running_in_test_harness /* Not fudged */ | |
3018 | ) || /* OR */ | |
3019 | expansion_test /* expansion testing */ | |
3020 | || /* OR */ | |
f05da2e8 | 3021 | filter_test != FTEST_NONE) /* Filter testing */ |
059ec3d9 PH |
3022 | { |
3023 | setgroups(group_count, group_list); | |
3024 | exim_setugid(real_uid, real_gid, FALSE, | |
3025 | US"-C, -D, -be or -bf forces real uid"); | |
3026 | removed_privilege = TRUE; | |
3027 | ||
3028 | /* In the normal case when Exim is called like this, stderr is available | |
3029 | and should be used for any logging information because attempts to write | |
3030 | to the log will usually fail. To arrange this, we unset really_exim. However, | |
3031 | if no stderr is available there is no point - we might as well have a go | |
3032 | at the log (if it fails, syslog will be written). */ | |
3033 | ||
3034 | if (log_stderr != NULL) really_exim = FALSE; | |
3035 | } | |
3036 | ||
3037 | /* Privilege is to be retained for the moment. It may be dropped later, | |
3038 | depending on the job that this Exim process has been asked to do. For now, set | |
3039 | the real uid to the effective so that subsequent re-execs of Exim are done by a | |
3040 | privileged user. */ | |
3041 | ||
3042 | else exim_setugid(geteuid(), getegid(), FALSE, US"forcing real = effective"); | |
3043 | ||
f05da2e8 | 3044 | /* If testing a filter, open the file(s) now, before wasting time doing other |
059ec3d9 PH |
3045 | setups and reading the message. */ |
3046 | ||
f05da2e8 PH |
3047 | if ((filter_test & FTEST_SYSTEM) != 0) |
3048 | { | |
3049 | filter_sfd = Uopen(filter_test_sfile, O_RDONLY, 0); | |
3050 | if (filter_sfd < 0) | |
3051 | { | |
3052 | fprintf(stderr, "exim: failed to open %s: %s\n", filter_test_sfile, | |
3053 | strerror(errno)); | |
3054 | return EXIT_FAILURE; | |
3055 | } | |
3056 | } | |
3057 | ||
3058 | if ((filter_test & FTEST_USER) != 0) | |
059ec3d9 | 3059 | { |
f05da2e8 PH |
3060 | filter_ufd = Uopen(filter_test_ufile, O_RDONLY, 0); |
3061 | if (filter_ufd < 0) | |
059ec3d9 | 3062 | { |
f05da2e8 | 3063 | fprintf(stderr, "exim: failed to open %s: %s\n", filter_test_ufile, |
059ec3d9 PH |
3064 | strerror(errno)); |
3065 | return EXIT_FAILURE; | |
3066 | } | |
3067 | } | |
3068 | ||
3069 | /* Read the main runtime configuration data; this gives up if there | |
3070 | is a failure. It leaves the configuration file open so that the subsequent | |
3071 | configuration data for delivery can be read if needed. */ | |
3072 | ||
3073 | readconf_main(); | |
3074 | ||
3075 | /* Handle the decoding of logging options. */ | |
3076 | ||
1fe64dcc | 3077 | decode_bits(&log_write_selector, &log_extra_selector, 0, 0, log_selector_string, |
059ec3d9 PH |
3078 | log_options, log_options_count, US"log"); |
3079 | ||
3080 | DEBUG(D_any) | |
3081 | { | |
3082 | debug_printf("configuration file is %s\n", config_main_filename); | |
3083 | debug_printf("log selectors = %08x %08x\n", log_write_selector, | |
3084 | log_extra_selector); | |
3085 | } | |
3086 | ||
3087 | /* If domain literals are not allowed, check the sender address that was | |
3088 | supplied with -f. Ditto for a stripped trailing dot. */ | |
3089 | ||
3090 | if (sender_address != NULL) | |
3091 | { | |
3092 | if (sender_address[sender_address_domain] == '[' && !allow_domain_literals) | |
3093 | { | |
3094 | fprintf(stderr, "exim: bad -f address \"%s\": domain literals not " | |
3095 | "allowed\n", sender_address); | |
3096 | return EXIT_FAILURE; | |
3097 | } | |
3098 | if (f_end_dot && !strip_trailing_dot) | |
3099 | { | |
3100 | fprintf(stderr, "exim: bad -f address \"%s.\": domain is malformed " | |
3101 | "(trailing dot not allowed)\n", sender_address); | |
3102 | return EXIT_FAILURE; | |
3103 | } | |
3104 | } | |
3105 | ||
3106 | /* Paranoia check of maximum lengths of certain strings. There is a check | |
3107 | on the length of the log file path in log.c, which will come into effect | |
3108 | if there are any calls to write the log earlier than this. However, if we | |
3109 | get this far but the string is very long, it is better to stop now than to | |
3110 | carry on and (e.g.) receive a message and then have to collapse. The call to | |
3111 | log_write() from here will cause the ultimate panic collapse if the complete | |
3112 | file name exceeds the buffer length. */ | |
3113 | ||
3114 | if (Ustrlen(log_file_path) > 200) | |
3115 | log_write(0, LOG_MAIN|LOG_PANIC_DIE, | |
3116 | "log_file_path is longer than 200 chars: aborting"); | |
3117 | ||
3118 | if (Ustrlen(pid_file_path) > 200) | |
3119 | log_write(0, LOG_MAIN|LOG_PANIC_DIE, | |
3120 | "pid_file_path is longer than 200 chars: aborting"); | |
3121 | ||
3122 | if (Ustrlen(spool_directory) > 200) | |
3123 | log_write(0, LOG_MAIN|LOG_PANIC_DIE, | |
3124 | "spool_directory is longer than 200 chars: aborting"); | |
3125 | ||
3126 | /* Length check on the process name given to syslog for its TAG field, | |
3127 | which is only permitted to be 32 characters or less. See RFC 3164. */ | |
3128 | ||
3129 | if (Ustrlen(syslog_processname) > 32) | |
3130 | log_write(0, LOG_MAIN|LOG_PANIC_DIE, | |
3131 | "syslog_processname is longer than 32 chars: aborting"); | |
3132 | ||
3133 | /* In some operating systems, the environment variable TMPDIR controls where | |
3134 | temporary files are created; Exim doesn't use these (apart from when delivering | |
3135 | to MBX mailboxes), but called libraries such as DBM libraries may require them. | |
3136 | If TMPDIR is found in the environment, reset it to the value defined in the | |
3137 | TMPDIR macro, if this macro is defined. */ | |
3138 | ||
3139 | #ifdef TMPDIR | |
3140 | { | |
3141 | uschar **p; | |
3142 | for (p = USS environ; *p != NULL; p++) | |
3143 | { | |
3144 | if (Ustrncmp(*p, "TMPDIR=", 7) == 0 && | |
3145 | Ustrcmp(*p+7, TMPDIR) != 0) | |
3146 | { | |
3147 | uschar *newp = malloc(Ustrlen(TMPDIR) + 8); | |
3148 | sprintf(CS newp, "TMPDIR=%s", TMPDIR); | |
3149 | *p = newp; | |
3150 | DEBUG(D_any) debug_printf("reset TMPDIR=%s in environment\n", TMPDIR); | |
3151 | } | |
3152 | } | |
3153 | } | |
3154 | #endif | |
3155 | ||
3156 | /* Timezone handling. If timezone_string is "utc", set a flag to cause all | |
3157 | timestamps to be in UTC (gmtime() is used instead of localtime()). Otherwise, | |
3158 | we may need to get rid of a bogus timezone setting. This can arise when Exim is | |
3159 | called by a user who has set the TZ variable. This then affects the timestamps | |
3160 | in log files and in Received: headers, and any created Date: header lines. The | |
3161 | required timezone is settable in the configuration file, so nothing can be done | |
3162 | about this earlier - but hopefully nothing will normally be logged earlier than | |
3163 | this. We have to make a new environment if TZ is wrong, but don't bother if | |
3164 | timestamps_utc is set, because then all times are in UTC anyway. */ | |
3165 | ||
3166 | if (timezone_string != NULL && strcmpic(timezone_string, US"UTC") == 0) | |
3167 | { | |
3168 | timestamps_utc = TRUE; | |
3169 | } | |
3170 | else | |
3171 | { | |
3172 | uschar *envtz = US getenv("TZ"); | |
3173 | if ((envtz == NULL && timezone_string != NULL) || | |
3174 | (envtz != NULL && | |
3175 | (timezone_string == NULL || | |
3176 | Ustrcmp(timezone_string, envtz) != 0))) | |
3177 | { | |
3178 | uschar **p = USS environ; | |
3179 | uschar **new; | |
3180 | uschar **newp; | |
3181 | int count = 0; | |
3182 | while (*p++ != NULL) count++; | |
3183 | if (envtz == NULL) count++; | |
3184 | newp = new = malloc(sizeof(uschar *) * (count + 1)); | |
3185 | for (p = USS environ; *p != NULL; p++) | |
3186 | { | |
3187 | if (Ustrncmp(*p, "TZ=", 3) == 0) continue; | |
3188 | *newp++ = *p; | |
3189 | } | |
3190 | if (timezone_string != NULL) | |
3191 | { | |
3192 | *newp = malloc(Ustrlen(timezone_string) + 4); | |
3193 | sprintf(CS *newp++, "TZ=%s", timezone_string); | |
3194 | } | |
3195 | *newp = NULL; | |
3196 | environ = CSS new; | |
3197 | tzset(); | |
3198 | DEBUG(D_any) debug_printf("Reset TZ to %s: time is %s\n", timezone_string, | |
3199 | tod_stamp(tod_log)); | |
3200 | } | |
3201 | } | |
3202 | ||
3203 | /* Handle the case when we have removed the setuid privilege because of -C or | |
3204 | -D. This means that the caller of Exim was not root, and, provided that | |
3205 | ALT_CONFIG_ROOT_ONLY is not defined, was not the Exim user that is built into | |
3206 | the binary. | |
3207 | ||
3208 | If ALT_CONFIG_ROOT_ONLY is not defined, there is a problem if it turns out we | |
3209 | were running as the exim user defined in the configuration file (different to | |
3210 | the one in the binary). The sysadmin may expect this case to retain privilege | |
3211 | because "the binary was called by the Exim user", but it hasn't, because of the | |
3212 | order in which it handles this stuff. There are two possibilities: | |
3213 | ||
3214 | (1) If deliver_drop_privilege is set, Exim is not going to re-exec in order | |
3215 | to do message deliveries. Thus, the fact that it is running as a | |
3216 | non-privileged user is plausible, and might be wanted in some special | |
3217 | configurations. However, really_exim will have been set false when | |
3218 | privilege was dropped, to stop Exim trying to write to its normal log | |
3219 | files. Therefore, re-enable normal log processing, assuming the sysadmin | |
3220 | has set up the log directory correctly. | |
3221 | ||
3222 | (2) If deliver_drop_privilege is not set, the configuration won't work as | |
3223 | apparently intended, and so we log a panic message. In order to retain | |
3224 | root for -C or -D, the caller must either be root or the Exim user | |
3225 | defined in the binary (when deliver_drop_ privilege is false). | |
3226 | ||
3227 | If ALT_CONFIG_ROOT_ONLY is defined, we don't know whether we were called by the | |
3228 | built-in exim user or one defined in the configuration. In either event, | |
3229 | re-enable log processing, assuming the sysadmin knows what they are doing. */ | |
3230 | ||
3231 | if (removed_privilege && (config_changed || macros != NULL) && | |
3232 | real_uid == exim_uid) | |
3233 | { | |
3234 | #ifdef ALT_CONFIG_ROOT_ONLY | |
3235 | really_exim = TRUE; /* let logging work normally */ | |
3236 | #else | |
3237 | ||
3238 | if (deliver_drop_privilege) | |
3239 | really_exim = TRUE; /* let logging work normally */ | |
3240 | else | |
3241 | log_write(0, LOG_MAIN|LOG_PANIC, | |
3242 | "exim user (uid=%d) is defined only at runtime; privilege lost for %s", | |
3243 | (int)exim_uid, config_changed? "-C" : "-D"); | |
3244 | #endif | |
3245 | } | |
3246 | ||
3247 | /* Start up Perl interpreter if Perl support is configured and there is a | |
3248 | perl_startup option, and the configuration or the command line specifies | |
3249 | initializing starting. Note that the global variables are actually called | |
3250 | opt_perl_xxx to avoid clashing with perl's namespace (perl_*). */ | |
3251 | ||
3252 | #ifdef EXIM_PERL | |
3253 | if (perl_start_option != 0) | |
3254 | opt_perl_at_start = (perl_start_option > 0); | |
3255 | if (opt_perl_at_start && opt_perl_startup != NULL) | |
3256 | { | |
3257 | uschar *errstr; | |
3258 | DEBUG(D_any) debug_printf("Starting Perl interpreter\n"); | |
3259 | errstr = init_perl(opt_perl_startup); | |
3260 | if (errstr != NULL) | |
3261 | { | |
3262 | fprintf(stderr, "exim: error in perl_startup code: %s\n", errstr); | |
3263 | return EXIT_FAILURE; | |
3264 | } | |
3265 | opt_perl_started = TRUE; | |
3266 | } | |
3267 | #endif /* EXIM_PERL */ | |
3268 | ||
3269 | /* Log the arguments of the call if the configuration file said so. This is | |
3270 | a debugging feature for finding out what arguments certain MUAs actually use. | |
3271 | Don't attempt it if logging is disabled, or if listing variables or if | |
3272 | verifying/testing addresses or expansions. */ | |
3273 | ||
31619da6 PH |
3274 | if (((debug_selector & D_any) != 0 || (log_extra_selector & LX_arguments) != 0) |
3275 | && really_exim && !list_options && !checking) | |
059ec3d9 PH |
3276 | { |
3277 | int i; | |
3278 | uschar *p = big_buffer; | |
3279 | Ustrcpy(p, "cwd="); | |
3280 | (void)getcwd(CS p+4, big_buffer_size - 4); | |
3281 | while (*p) p++; | |
3282 | (void)string_format(p, big_buffer_size - (p - big_buffer), " %d args:", argc); | |
3283 | while (*p) p++; | |
3284 | for (i = 0; i < argc; i++) | |
3285 | { | |
3286 | int len = Ustrlen(argv[i]); | |
3287 | uschar *printing; | |
3288 | uschar *quote; | |
3289 | if (p + len + 8 >= big_buffer + big_buffer_size) | |
3290 | { | |
3291 | Ustrcpy(p, " ..."); | |
3292 | log_write(0, LOG_MAIN, "%s", big_buffer); | |
3293 | Ustrcpy(big_buffer, "..."); | |
3294 | p = big_buffer + 3; | |
3295 | } | |
3296 | printing = string_printing(argv[i]); | |
3297 | if (printing[0] == 0) quote = US"\""; else | |
3298 | { | |
3299 | uschar *pp = printing; | |
3300 | quote = US""; | |
3301 | while (*pp != 0) if (isspace(*pp++)) { quote = US"\""; break; } | |
3302 | } | |
3303 | sprintf(CS p, " %s%.*s%s", quote, (int)(big_buffer_size - | |
3304 | (p - big_buffer) - 4), printing, quote); | |
3305 | while (*p) p++; | |
3306 | } | |
31619da6 PH |
3307 | |
3308 | if ((log_extra_selector & LX_arguments) != 0) | |
3309 | log_write(0, LOG_MAIN, "%s", big_buffer); | |
3310 | else | |
3311 | debug_printf("%s\n", big_buffer); | |
059ec3d9 PH |
3312 | } |
3313 | ||
3314 | /* Set the working directory to be the top-level spool directory. We don't rely | |
3315 | on this in the code, which always uses fully qualified names, but it's useful | |
3316 | for core dumps etc. Don't complain if it fails - the spool directory might not | |
3317 | be generally accessible and calls with the -C option (and others) have lost | |
ba18e66a PH |
3318 | privilege by now. Before the chdir, we try to ensure that the directory exists. |
3319 | */ | |
059ec3d9 PH |
3320 | |
3321 | if (Uchdir(spool_directory) != 0) | |
3322 | { | |
ba18e66a | 3323 | (void)directory_make(spool_directory, US"", SPOOL_DIRECTORY_MODE, FALSE); |
059ec3d9 PH |
3324 | (void)Uchdir(spool_directory); |
3325 | } | |
3326 | ||
3327 | /* Handle calls with the -bi option. This is a sendmail option to rebuild *the* | |
3328 | alias file. Exim doesn't have such a concept, but this call is screwed into | |
3329 | Sun's YP makefiles. Handle this by calling a configured script, as the real | |
3330 | user who called Exim. The -oA option can be used to pass an argument to the | |
3331 | script. */ | |
3332 | ||
3333 | if (bi_option) | |
3334 | { | |
1fe64dcc | 3335 | (void)fclose(config_file); |
059ec3d9 PH |
3336 | if (bi_command != NULL) |
3337 | { | |
3338 | int i = 0; | |
3339 | uschar *argv[3]; | |
3340 | argv[i++] = bi_command; | |
3341 | if (alias_arg != NULL) argv[i++] = alias_arg; | |
3342 | argv[i++] = NULL; | |
3343 | ||
3344 | setgroups(group_count, group_list); | |
3345 | exim_setugid(real_uid, real_gid, FALSE, US"running bi_command"); | |
3346 | ||
3347 | DEBUG(D_exec) debug_printf("exec %.256s %.256s\n", argv[0], | |
3348 | (argv[1] == NULL)? US"" : argv[1]); | |
3349 | ||
3350 | execv(CS argv[0], (char *const *)argv); | |
3351 | fprintf(stderr, "exim: exec failed: %s\n", strerror(errno)); | |
3352 | exit(EXIT_FAILURE); | |
3353 | } | |
3354 | else | |
3355 | { | |
3356 | DEBUG(D_any) debug_printf("-bi used but bi_command not set; exiting\n"); | |
3357 | exit(EXIT_SUCCESS); | |
3358 | } | |
3359 | } | |
3360 | ||
3361 | /* If an action on specific messages is requested, or if a daemon or queue | |
3362 | runner is being started, we need to know if Exim was called by an admin user. | |
3363 | This is the case if the real user is root or exim, or if the real group is | |
3364 | exim, or if one of the supplementary groups is exim or a group listed in | |
3365 | admin_groups. We don't fail all message actions immediately if not admin_user, | |
3366 | since some actions can be performed by non-admin users. Instead, set admin_user | |
3367 | for later interrogation. */ | |
3368 | ||
3369 | if (real_uid == root_uid || real_uid == exim_uid || real_gid == exim_gid) | |
3370 | admin_user = TRUE; | |
3371 | else | |
3372 | { | |
3373 | int i, j; | |
3374 | ||
3375 | for (i = 0; i < group_count; i++) | |
3376 | { | |
3377 | if (group_list[i] == exim_gid) admin_user = TRUE; | |
3378 | else if (admin_groups != NULL) | |
3379 | { | |
3380 | for (j = 1; j <= (int)(admin_groups[0]); j++) | |
3381 | if (admin_groups[j] == group_list[i]) | |
3382 | { admin_user = TRUE; break; } | |
3383 | } | |
3384 | if (admin_user) break; | |
3385 | } | |
3386 | } | |
3387 | ||
3388 | /* Another group of privileged users are the trusted users. These are root, | |
3389 | exim, and any caller matching trusted_users or trusted_groups. Trusted callers | |
3390 | are permitted to specify sender_addresses with -f on the command line, and | |
3391 | other message parameters as well. */ | |
3392 | ||
3393 | if (real_uid == root_uid || real_uid == exim_uid) | |
3394 | trusted_caller = TRUE; | |
3395 | else | |
3396 | { | |
3397 | int i, j; | |
3398 | ||
3399 | if (trusted_users != NULL) | |
3400 | { | |
3401 | for (i = 1; i <= (int)(trusted_users[0]); i++) | |
3402 | if (trusted_users[i] == real_uid) | |
3403 | { trusted_caller = TRUE; break; } | |
3404 | } | |
3405 | ||
3406 | if (!trusted_caller && trusted_groups != NULL) | |
3407 | { | |
3408 | for (i = 1; i <= (int)(trusted_groups[0]); i++) | |
3409 | { | |
3410 | if (trusted_groups[i] == real_gid) | |
3411 | trusted_caller = TRUE; | |
3412 | else for (j = 0; j < group_count; j++) | |
3413 | { | |
3414 | if (trusted_groups[i] == group_list[j]) | |
3415 | { trusted_caller = TRUE; break; } | |
3416 | } | |
3417 | if (trusted_caller) break; | |
3418 | } | |
3419 | } | |
3420 | } | |
3421 | ||
3422 | if (trusted_caller) DEBUG(D_any) debug_printf("trusted user\n"); | |
3423 | if (admin_user) DEBUG(D_any) debug_printf("admin user\n"); | |
3424 | ||
3425 | /* Only an admin user may start the daemon or force a queue run in the default | |
3426 | configuration, but the queue run restriction can be relaxed. Only an admin | |
3427 | user may request that a message be returned to its sender forthwith. Only an | |
3428 | admin user may specify a debug level greater than D_v (because it might show | |
3429 | passwords, etc. in lookup queries). Only an admin user may request a queue | |
3430 | count. */ | |
3431 | ||
3432 | if (!admin_user) | |
3433 | { | |
3434 | BOOL debugset = (debug_selector & ~D_v) != 0; | |
3435 | if (deliver_give_up || daemon_listen || | |
3436 | (count_queue && queue_list_requires_admin) || | |
3437 | (list_queue && queue_list_requires_admin) || | |
3438 | (queue_interval >= 0 && prod_requires_admin) || | |
3439 | (debugset && !running_in_test_harness)) | |
3440 | { | |
3441 | fprintf(stderr, "exim:%s permission denied\n", debugset? " debugging" : ""); | |
3442 | exit(EXIT_FAILURE); | |
3443 | } | |
3444 | } | |
3445 | ||
3446 | /* If the real user is not root or the exim uid, the argument for passing | |
3447 | in an open TCP/IP connection for another message is not permitted, nor is | |
3448 | running with the -N option for any delivery action, unless this call to exim is | |
3449 | one that supplied an input message, or we are using a patched exim for | |
3450 | regression testing. */ | |
3451 | ||
3452 | if (real_uid != root_uid && real_uid != exim_uid && | |
3453 | (continue_hostname != NULL || | |
3454 | (dont_deliver && | |
3455 | (queue_interval >= 0 || daemon_listen || msg_action_arg > 0) | |
3456 | )) && !running_in_test_harness) | |
3457 | { | |
3458 | fprintf(stderr, "exim: Permission denied\n"); | |
3459 | return EXIT_FAILURE; | |
3460 | } | |
3461 | ||
3462 | /* If the caller is not trusted, certain arguments are ignored when running for | |
f05da2e8 PH |
3463 | real, but are permitted when checking things (-be, -bv, -bt, -bh, -bf, -bF). |
3464 | Note that authority for performing certain actions on messages is tested in the | |
059ec3d9 PH |
3465 | queue_action() function. */ |
3466 | ||
f05da2e8 | 3467 | if (!trusted_caller && !checking && filter_test == FTEST_NONE) |
059ec3d9 PH |
3468 | { |
3469 | sender_host_name = sender_host_address = interface_address = | |
3470 | sender_ident = received_protocol = NULL; | |
3471 | sender_host_port = interface_port = 0; | |
3472 | sender_host_authenticated = authenticated_sender = authenticated_id = NULL; | |
3473 | } | |
3474 | ||
3475 | /* If a sender host address is set, extract the optional port number off the | |
3476 | end of it and check its syntax. Do the same thing for the interface address. | |
3477 | Exim exits if the syntax is bad. */ | |
3478 | ||
3479 | else | |
3480 | { | |
3481 | if (sender_host_address != NULL) | |
3482 | sender_host_port = check_port(sender_host_address); | |
3483 | if (interface_address != NULL) | |
3484 | interface_port = check_port(interface_address); | |
3485 | } | |
3486 | ||
3487 | /* If an SMTP message is being received check to see if the standard input is a | |
3488 | TCP/IP socket. If it is, we assume that Exim was called from inetd if the | |
3489 | caller is root or the Exim user, or if the port is a privileged one. Otherwise, | |
3490 | barf. */ | |
3491 | ||
3492 | if (smtp_input) | |
3493 | { | |
3494 | union sockaddr_46 inetd_sock; | |
36a3b041 | 3495 | EXIM_SOCKLEN_T size = sizeof(inetd_sock); |
059ec3d9 PH |
3496 | if (getpeername(0, (struct sockaddr *)(&inetd_sock), &size) == 0) |
3497 | { | |
3498 | int family = ((struct sockaddr *)(&inetd_sock))->sa_family; | |
3499 | if (family == AF_INET || family == AF_INET6) | |
3500 | { | |
3501 | union sockaddr_46 interface_sock; | |
3502 | size = sizeof(interface_sock); | |
3503 | ||
3504 | if (getsockname(0, (struct sockaddr *)(&interface_sock), &size) == 0) | |
3505 | interface_address = host_ntoa(-1, &interface_sock, NULL, | |
3506 | &interface_port); | |
3507 | ||
3508 | if (host_is_tls_on_connect_port(interface_port)) tls_on_connect = TRUE; | |
3509 | ||
3510 | if (real_uid == root_uid || real_uid == exim_uid || interface_port < 1024) | |
3511 | { | |
3512 | is_inetd = TRUE; | |
3513 | sender_host_address = host_ntoa(-1, (struct sockaddr *)(&inetd_sock), | |
3514 | NULL, &sender_host_port); | |
3515 | if (mua_wrapper) log_write(0, LOG_MAIN|LOG_PANIC_DIE, "Input from " | |
3516 | "inetd is not supported when mua_wrapper is set"); | |
3517 | } | |
3518 | else | |
3519 | { | |
3520 | fprintf(stderr, | |
3521 | "exim: Permission denied (unprivileged user, unprivileged port)\n"); | |
3522 | return EXIT_FAILURE; | |
3523 | } | |
3524 | } | |
3525 | } | |
3526 | } | |
3527 | ||
3528 | /* If the load average is going to be needed while receiving a message, get it | |
3529 | now for those OS that require the first call to os_getloadavg() to be done as | |
3530 | root. There will be further calls later for each message received. */ | |
3531 | ||
3532 | #ifdef LOAD_AVG_NEEDS_ROOT | |
3533 | if (receiving_message && | |
3534 | (queue_only_load >= 0 || | |
3535 | (is_inetd && smtp_load_reserve >= 0) | |
3536 | )) | |
3537 | { | |
3538 | load_average = os_getloadavg(); | |
3539 | } | |
3540 | #endif | |
3541 | ||
3542 | /* The queue_only configuration option can be overridden by -odx on the command | |
3543 | line, except that if queue_only_override is false, queue_only cannot be unset | |
3544 | from the command line. */ | |
3545 | ||
3546 | if (queue_only_set && (queue_only_override || arg_queue_only)) | |
3547 | queue_only = arg_queue_only; | |
3548 | ||
3549 | /* The receive_timeout and smtp_receive_timeout options can be overridden by | |
3550 | -or and -os. */ | |
3551 | ||
3552 | if (arg_receive_timeout >= 0) receive_timeout = arg_receive_timeout; | |
3553 | if (arg_smtp_receive_timeout >= 0) | |
3554 | smtp_receive_timeout = arg_smtp_receive_timeout; | |
3555 | ||
3556 | /* If Exim was started with root privilege, unless we have already removed the | |
3557 | root privilege above as a result of -C, -D, -be, -bf or -bF, remove it now | |
3558 | except when starting the daemon or doing some kind of delivery or address | |
3559 | testing (-bt). These are the only cases when root need to be retained. We run | |
3560 | as exim for -bv and -bh. However, if deliver_drop_privilege is set, root is | |
3561 | retained only for starting the daemon. */ | |
3562 | ||
3563 | if (!unprivileged && /* originally had root AND */ | |
3564 | !removed_privilege && /* still got root AND */ | |
3565 | !daemon_listen && /* not starting the daemon */ | |
3566 | queue_interval <= 0 && /* (either kind of daemon) */ | |
3567 | ( /* AND EITHER */ | |
3568 | deliver_drop_privilege || /* requested unprivileged */ | |
3569 | ( /* OR */ | |
3570 | queue_interval < 0 && /* not running the queue */ | |
3571 | (msg_action_arg < 0 || /* and */ | |
3572 | msg_action != MSG_DELIVER) && /* not delivering and */ | |
3573 | (!checking || !address_test_mode) /* not address checking */ | |
3574 | ) | |
3575 | )) | |
3576 | { | |
3577 | exim_setugid(exim_uid, exim_gid, FALSE, US"privilege not needed"); | |
3578 | } | |
3579 | ||
3580 | /* When we are retaining a privileged uid, we still change to the exim gid. */ | |
3581 | ||
3582 | else setgid(exim_gid); | |
3583 | ||
3584 | /* Handle a request to list the delivery queue */ | |
3585 | ||
3586 | if (list_queue) | |
3587 | { | |
3588 | set_process_info("listing the queue"); | |
3589 | queue_list(list_queue_option, argv + recipients_arg, argc - recipients_arg); | |
3590 | exit(EXIT_SUCCESS); | |
3591 | } | |
3592 | ||
3593 | /* Handle a request to count the delivery queue */ | |
3594 | ||
3595 | if (count_queue) | |
3596 | { | |
3597 | set_process_info("counting the queue"); | |
3598 | queue_count(); | |
3599 | exit(EXIT_SUCCESS); | |
3600 | } | |
3601 | ||
3602 | /* Handle actions on specific messages, except for the force delivery action, | |
3603 | which is done below. Some actions take a whole list of message ids, which | |
3604 | are known to continue up to the end of the arguments. Others take a single | |
3605 | message id and then operate on the recipients list. */ | |
3606 | ||
3607 | if (msg_action_arg > 0 && msg_action != MSG_DELIVER) | |
3608 | { | |
3609 | int yield = EXIT_SUCCESS; | |
3610 | set_process_info("acting on specified messages"); | |
3611 | ||
3612 | if (!one_msg_action) | |
3613 | { | |
3614 | for (i = msg_action_arg; i < argc; i++) | |
3615 | if (!queue_action(argv[i], msg_action, NULL, 0, 0)) | |
3616 | yield = EXIT_FAILURE; | |
3617 | } | |
3618 | ||
3619 | else if (!queue_action(argv[msg_action_arg], msg_action, argv, argc, | |
3620 | recipients_arg)) yield = EXIT_FAILURE; | |
3621 | exit(yield); | |
3622 | } | |
3623 | ||
3624 | /* All the modes below here require the remaining configuration sections | |
3625 | to be read, except that we can skip over the ACL setting when delivering | |
3626 | specific messages, or doing a queue run. (For various testing cases we could | |
3627 | skip too, but as they are rare, it doesn't really matter.) The argument is TRUE | |
3628 | for skipping. */ | |
3629 | ||
3630 | readconf_rest(msg_action_arg > 0 || (queue_interval == 0 && !daemon_listen)); | |
3631 | ||
3632 | /* The configuration data will have been read into POOL_PERM because we won't | |
3633 | ever want to reset back past it. Change the current pool to POOL_MAIN. In fact, | |
3634 | this is just a bit of pedantic tidiness. It wouldn't really matter if the | |
3635 | configuration were read into POOL_MAIN, because we don't do any resets till | |
3636 | later on. However, it seems right, and it does ensure that both pools get used. | |
3637 | */ | |
3638 | ||
3639 | store_pool = POOL_MAIN; | |
3640 | ||
3641 | /* Handle the -brt option. This is for checking out retry configurations. | |
3642 | The next three arguments are a domain name or a complete address, and | |
3643 | optionally two error numbers. All it does is to call the function that | |
3644 | scans the retry configuration data. */ | |
3645 | ||
3646 | if (test_retry_arg >= 0) | |
3647 | { | |
3648 | retry_config *yield; | |
3649 | int basic_errno = 0; | |
3650 | int more_errno = 0; | |
3651 | uschar *s1, *s2; | |
3652 | ||
3653 | if (test_retry_arg >= argc) | |
3654 | { | |
3655 | printf("-brt needs a domain or address argument\n"); | |
3656 | exim_exit(EXIT_FAILURE); | |
3657 | } | |
3658 | s1 = argv[test_retry_arg++]; | |
3659 | s2 = NULL; | |
3660 | ||
3661 | /* If the first argument contains no @ and no . it might be a local user | |
3662 | or it might be a single-component name. Treat as a domain. */ | |
3663 | ||
3664 | if (Ustrchr(s1, '@') == NULL && Ustrchr(s1, '.') == NULL) | |
3665 | { | |
3666 | printf("Warning: \"%s\" contains no '@' and no '.' characters. It is " | |
3667 | "being \ntreated as a one-component domain, not as a local part.\n\n", | |
3668 | s1); | |
3669 | } | |
3670 | ||
3671 | /* There may be an optional second domain arg. */ | |
3672 | ||
3673 | if (test_retry_arg < argc && Ustrchr(argv[test_retry_arg], '.') != NULL) | |
3674 | s2 = argv[test_retry_arg++]; | |
3675 | ||
3676 | /* The final arg is an error name */ | |
3677 | ||
3678 | if (test_retry_arg < argc) | |
3679 | { | |
3680 | uschar *ss = argv[test_retry_arg]; | |
3681 | uschar *error = | |
3682 | readconf_retry_error(ss, ss + Ustrlen(ss), &basic_errno, &more_errno); | |
3683 | if (error != NULL) | |
3684 | { | |
3685 | printf("%s\n", CS error); | |
3686 | return EXIT_FAILURE; | |
3687 | } | |
3688 | ||
3689 | /* For the rcpt_4xx errors, a value of 255 means "any", and a code > 100 as | |
3690 | an error is for matching codes to the decade. Turn them into a real error | |
3691 | code, off the decade. */ | |
3692 | ||
3693 | if (basic_errno == ERRNO_RCPT4XX) | |
3694 | { | |
3695 | int code = (more_errno >> 8) & 255; | |
3696 | if (code == 255) | |
3697 | more_errno = (more_errno & 0xffff00ff) | (21 << 8); | |
3698 | else if (code > 100) | |
3699 | more_errno = (more_errno & 0xffff00ff) | ((code - 96) << 8); | |
3700 | } | |
3701 | } | |
3702 | ||
3703 | yield = retry_find_config(s1, s2, basic_errno, more_errno); | |
3704 | if (yield == NULL) printf("No retry information found\n"); else | |
3705 | { | |
3706 | retry_rule *r; | |
3707 | more_errno = yield->more_errno; | |
3708 | printf("Retry rule: %s ", yield->pattern); | |
3709 | ||
3710 | if (yield->basic_errno == ERRNO_EXIMQUOTA) | |
3711 | { | |
3712 | printf("quota%s%s ", | |
3713 | (more_errno > 0)? "_" : "", | |
3714 | (more_errno > 0)? readconf_printtime(more_errno) : US""); | |
3715 | } | |
3716 | else if (yield->basic_errno == ECONNREFUSED) | |
3717 | { | |
3718 | printf("refused%s%s ", | |
3719 | (more_errno > 0)? "_" : "", | |
3720 | (more_errno == 'M')? "MX" : | |
3721 | (more_errno == 'A')? "A" : ""); | |
3722 | } | |
3723 | else if (yield->basic_errno == ETIMEDOUT) | |
3724 | { | |
3725 | printf("timeout"); | |
3726 | if ((more_errno & RTEF_CTOUT) != 0) printf("_connect"); | |
3727 | more_errno &= 255; | |
3728 | if (more_errno != 0) printf("_%s", | |
3729 | (more_errno == 'M')? "MX" : "A"); | |
3730 | printf(" "); | |
3731 | } | |
3732 | else if (yield->basic_errno == ERRNO_AUTHFAIL) | |
3733 | printf("auth_failed "); | |
3734 | else printf("* "); | |
3735 | ||
3736 | for (r = yield->rules; r != NULL; r = r->next) | |
3737 | { | |
3738 | printf("%c,%s", r->rule, readconf_printtime(r->timeout)); /* Do not */ | |
3739 | printf(",%s", readconf_printtime(r->p1)); /* amalgamate */ | |
3740 | if (r->rule == 'G') | |
3741 | { | |
3742 | int x = r->p2; | |
3743 | int f = x % 1000; | |
3744 | int d = 100; | |
3745 | printf(",%d.", x/1000); | |
3746 | do | |
3747 | { | |
3748 | printf("%d", f/d); | |
3749 | f %= d; | |
3750 | d /= 10; | |
3751 | } | |
3752 | while (f != 0); | |
3753 | } | |
3754 | printf("; "); | |
3755 | } | |
3756 | ||
3757 | printf("\n"); | |
3758 | } | |
3759 | exim_exit(EXIT_SUCCESS); | |
3760 | } | |
3761 | ||
3762 | /* Handle a request to list one or more configuration options */ | |
3763 | ||
3764 | if (list_options) | |
3765 | { | |
3766 | set_process_info("listing variables"); | |
3767 | if (recipients_arg >= argc) readconf_print(US"all", NULL); | |
3768 | else for (i = recipients_arg; i < argc; i++) | |
3769 | { | |
3770 | if (i < argc - 1 && | |
3771 | (Ustrcmp(argv[i], "router") == 0 || | |
3772 | Ustrcmp(argv[i], "transport") == 0 || | |
3773 | Ustrcmp(argv[i], "authenticator") == 0)) | |
3774 | { | |
3775 | readconf_print(argv[i+1], argv[i]); | |
3776 | i++; | |
3777 | } | |
3778 | else readconf_print(argv[i], NULL); | |
3779 | } | |
3780 | exim_exit(EXIT_SUCCESS); | |
3781 | } | |
3782 | ||
3783 | ||
3784 | /* Handle a request to deliver one or more messages that are already on the | |
3785 | queue. Values of msg_action other than MSG_DELIVER are dealt with above. This | |
3786 | is typically used for a small number when prodding by hand (when the option | |
3787 | forced_delivery will be set) or when re-execing to regain root privilege. | |
3788 | Each message delivery must happen in a separate process, so we fork a process | |
3789 | for each one, and run them sequentially so that debugging output doesn't get | |
3790 | intertwined, and to avoid spawning too many processes if a long list is given. | |
3791 | However, don't fork for the last one; this saves a process in the common case | |
3792 | when Exim is called to deliver just one message. */ | |
3793 | ||
3794 | if (msg_action_arg > 0) | |
3795 | { | |
3796 | if (prod_requires_admin && !admin_user) | |
3797 | { | |
3798 | fprintf(stderr, "exim: Permission denied\n"); | |
3799 | exim_exit(EXIT_FAILURE); | |
3800 | } | |
3801 | set_process_info("delivering specified messages"); | |
3802 | if (deliver_give_up) forced_delivery = deliver_force_thaw = TRUE; | |
3803 | for (i = msg_action_arg; i < argc; i++) | |
3804 | { | |
3805 | int status; | |
3806 | pid_t pid; | |
3807 | if (i == argc - 1) | |
3808 | (void)deliver_message(argv[i], forced_delivery, deliver_give_up); | |
3809 | else if ((pid = fork()) == 0) | |
3810 | { | |
3811 | (void)deliver_message(argv[i], forced_delivery, deliver_give_up); | |
3812 | _exit(EXIT_SUCCESS); | |
3813 | } | |
3814 | else if (pid < 0) | |
3815 | { | |
3816 | fprintf(stderr, "failed to fork delivery process for %s: %s\n", argv[i], | |
3817 | strerror(errno)); | |
3818 | exim_exit(EXIT_FAILURE); | |
3819 | } | |
3820 | else wait(&status); | |
3821 | } | |
3822 | exim_exit(EXIT_SUCCESS); | |
3823 | } | |
3824 | ||
3825 | ||
3826 | /* If only a single queue run is requested, without SMTP listening, we can just | |
3827 | turn into a queue runner, with an optional starting message id. */ | |
3828 | ||
3829 | if (queue_interval == 0 && !daemon_listen) | |
3830 | { | |
3831 | DEBUG(D_queue_run) debug_printf("Single queue run%s%s%s%s\n", | |
3832 | (start_queue_run_id == NULL)? US"" : US" starting at ", | |
3833 | (start_queue_run_id == NULL)? US"" : start_queue_run_id, | |
3834 | (stop_queue_run_id == NULL)? US"" : US" stopping at ", | |
3835 | (stop_queue_run_id == NULL)? US"" : stop_queue_run_id); | |
3836 | set_process_info("running the queue (single queue run)"); | |
3837 | queue_run(start_queue_run_id, stop_queue_run_id, FALSE); | |
3838 | exim_exit(EXIT_SUCCESS); | |
3839 | } | |
3840 | ||
3841 | ||
3842 | /* Find the login name of the real user running this process. This is always | |
3843 | needed when receiving a message, because it is written into the spool file. It | |
3844 | may also be used to construct a from: or a sender: header, and in this case we | |
3845 | need the user's full name as well, so save a copy of it, checked for RFC822 | |
3846 | syntax and munged if necessary, if it hasn't previously been set by the -F | |
3847 | argument. We may try to get the passwd entry more than once, in case NIS or | |
3848 | other delays are in evidence. Save the home directory for use in filter testing | |
3849 | (only). */ | |
3850 | ||
3851 | for (i = 0;;) | |
3852 | { | |
3853 | if ((pw = getpwuid(real_uid)) != NULL) | |
3854 | { | |
3855 | originator_login = string_copy(US pw->pw_name); | |
3856 | originator_home = string_copy(US pw->pw_dir); | |
3857 | ||
3858 | /* If user name has not been set by -F, set it from the passwd entry | |
3859 | unless -f has been used to set the sender address by a trusted user. */ | |
3860 | ||
3861 | if (originator_name == NULL) | |
3862 | { | |
3863 | if (sender_address == NULL || | |
f05da2e8 | 3864 | (!trusted_caller && filter_test == FTEST_NONE)) |
059ec3d9 PH |
3865 | { |
3866 | uschar *name = US pw->pw_gecos; | |
3867 | uschar *amp = Ustrchr(name, '&'); | |
3868 | uschar buffer[256]; | |
3869 | ||
3870 | /* Most Unix specify that a '&' character in the gecos field is | |
3871 | replaced by a copy of the login name, and some even specify that | |
3872 | the first character should be upper cased, so that's what we do. */ | |
3873 | ||
3874 | if (amp != NULL) | |
3875 | { | |
3876 | int loffset; | |
3877 | string_format(buffer, sizeof(buffer), "%.*s%n%s%s", | |
3878 | amp - name, name, &loffset, originator_login, amp + 1); | |
3879 | buffer[loffset] = toupper(buffer[loffset]); | |
3880 | name = buffer; | |
3881 | } | |
3882 | ||
3883 | /* If a pattern for matching the gecos field was supplied, apply | |
3884 | it and then expand the name string. */ | |
3885 | ||
3886 | if (gecos_pattern != NULL && gecos_name != NULL) | |
3887 | { | |
3888 | const pcre *re; | |
3889 | re = regex_must_compile(gecos_pattern, FALSE, TRUE); /* Use malloc */ | |
3890 | ||
3891 | if (regex_match_and_setup(re, name, 0, -1)) | |
3892 | { | |
3893 | uschar *new_name = expand_string(gecos_name); | |
3894 | expand_nmax = -1; | |
3895 | if (new_name != NULL) | |
3896 | { | |
3897 | DEBUG(D_receive) debug_printf("user name \"%s\" extracted from " | |
3898 | "gecos field \"%s\"\n", new_name, name); | |
3899 | name = new_name; | |
3900 | } | |
3901 | else DEBUG(D_receive) debug_printf("failed to expand gecos_name string " | |
3902 | "\"%s\": %s\n", gecos_name, expand_string_message); | |
3903 | } | |
3904 | else DEBUG(D_receive) debug_printf("gecos_pattern \"%s\" did not match " | |
3905 | "gecos field \"%s\"\n", gecos_pattern, name); | |
3906 | store_free((void *)re); | |
3907 | } | |
3908 | originator_name = string_copy(name); | |
3909 | } | |
3910 | ||
3911 | /* A trusted caller has used -f but not -F */ | |
3912 | ||
3913 | else originator_name = US""; | |
3914 | } | |
3915 | ||
3916 | /* Break the retry loop */ | |
3917 | ||
3918 | break; | |
3919 | } | |
3920 | ||
3921 | if (++i > finduser_retries) break; | |
3922 | sleep(1); | |
3923 | } | |
3924 | ||
3925 | /* If we cannot get a user login, log the incident and give up, unless the | |
3926 | configuration specifies something to use. When running in the test harness, | |
8800895a | 3927 | any setting of unknown_login overrides the actual name. */ |
059ec3d9 PH |
3928 | |
3929 | if (originator_login == NULL || running_in_test_harness) | |
3930 | { | |
3931 | if (unknown_login != NULL) | |
3932 | { | |
3933 | originator_login = expand_string(unknown_login); | |
3934 | if (originator_name == NULL && unknown_username != NULL) | |
3935 | originator_name = expand_string(unknown_username); | |
3936 | if (originator_name == NULL) originator_name = US""; | |
3937 | } | |
3938 | if (originator_login == NULL) | |
3939 | log_write(0, LOG_MAIN|LOG_PANIC_DIE, "Failed to get user name for uid %d", | |
3940 | (int)real_uid); | |
3941 | } | |
3942 | ||
3943 | /* Ensure that the user name is in a suitable form for use as a "phrase" in an | |
3944 | RFC822 address.*/ | |
3945 | ||
3946 | originator_name = string_copy(parse_fix_phrase(originator_name, | |
3947 | Ustrlen(originator_name), big_buffer, big_buffer_size)); | |
3948 | ||
3949 | /* If a message is created by this call of Exim, the uid/gid of its originator | |
3950 | are those of the caller. These values are overridden if an existing message is | |
3951 | read in from the spool. */ | |
3952 | ||
3953 | originator_uid = real_uid; | |
3954 | originator_gid = real_gid; | |
3955 | ||
3956 | DEBUG(D_receive) debug_printf("originator: uid=%d gid=%d login=%s name=%s\n", | |
3957 | (int)originator_uid, (int)originator_gid, originator_login, originator_name); | |
3958 | ||
3959 | /* Run in daemon and/or queue-running mode. The function daemon_go() never | |
3960 | returns. We leave this till here so that the originator_ fields are available | |
47c7a64a PH |
3961 | for incoming messages via the daemon. The daemon cannot be run in mua_wrapper |
3962 | mode. */ | |
059ec3d9 PH |
3963 | |
3964 | if (daemon_listen || queue_interval > 0) | |
3965 | { | |
47c7a64a PH |
3966 | if (mua_wrapper) |
3967 | { | |
3968 | fprintf(stderr, "Daemon cannot be run when mua_wrapper is set\n"); | |
3969 | log_write(0, LOG_MAIN|LOG_PANIC_DIE, "Daemon cannot be run when " | |
3970 | "mua_wrapper is set"); | |
3971 | } | |
059ec3d9 PH |
3972 | daemon_go(); |
3973 | } | |
3974 | ||
3975 | /* If the sender ident has not been set (by a trusted caller) set it to | |
3976 | the caller. This will get overwritten below for an inetd call. If a trusted | |
3977 | caller has set it empty, unset it. */ | |
3978 | ||
3979 | if (sender_ident == NULL) sender_ident = originator_login; | |
3980 | else if (sender_ident[0] == 0) sender_ident = NULL; | |
3981 | ||
3982 | /* Handle the -brw option, which is for checking out rewriting rules. Cause log | |
3983 | writes (on errors) to go to stderr instead. Can't do this earlier, as want the | |
3984 | originator_* variables set. */ | |
3985 | ||
3986 | if (test_rewrite_arg >= 0) | |
3987 | { | |
3988 | really_exim = FALSE; | |
3989 | if (test_rewrite_arg >= argc) | |
3990 | { | |
3991 | printf("-brw needs an address argument\n"); | |
3992 | exim_exit(EXIT_FAILURE); | |
3993 | } | |
3994 | rewrite_test(argv[test_rewrite_arg]); | |
3995 | exim_exit(EXIT_SUCCESS); | |
3996 | } | |
3997 | ||
3998 | /* A locally-supplied message is considered to be coming from a local user | |
3999 | unless a trusted caller supplies a sender address with -f, or is passing in the | |
4000 | message via SMTP (inetd invocation or otherwise). */ | |
4001 | ||
4002 | if ((sender_address == NULL && !smtp_input) || | |
f05da2e8 | 4003 | (!trusted_caller && filter_test == FTEST_NONE)) |
059ec3d9 PH |
4004 | { |
4005 | sender_local = TRUE; | |
4006 | ||
4007 | /* A trusted caller can supply authenticated_sender and authenticated_id | |
4008 | via -oMas and -oMai and if so, they will already be set. */ | |
4009 | ||
4010 | if (authenticated_sender == NULL) | |
4011 | authenticated_sender = string_sprintf("%s@%s", originator_login, | |
4012 | qualify_domain_sender); | |
4013 | if (authenticated_id == NULL) authenticated_id = originator_login; | |
4014 | } | |
4015 | ||
4016 | /* Trusted callers are always permitted to specify the sender address. | |
4017 | Untrusted callers may specify it if it matches untrusted_set_sender, or if what | |
4018 | is specified is the empty address. However, if a trusted caller does not | |
4019 | specify a sender address for SMTP input, we leave sender_address unset. This | |
4020 | causes the MAIL commands to be honoured. */ | |
4021 | ||
4022 | if ((!smtp_input && sender_address == NULL) || | |
4023 | !receive_check_set_sender(sender_address)) | |
4024 | { | |
4025 | /* Either the caller is not permitted to set a general sender, or this is | |
4026 | non-SMTP input and the trusted caller has not set a sender. If there is no | |
4027 | sender, or if a sender other than <> is set, override with the originator's | |
4028 | login (which will get qualified below), except when checking things. */ | |
4029 | ||
4030 | if (sender_address == NULL /* No sender_address set */ | |
4031 | || /* OR */ | |
4032 | (sender_address[0] != 0 && /* Non-empty sender address, AND */ | |
4033 | !checking && /* Not running tests, AND */ | |
f05da2e8 | 4034 | filter_test == FTEST_NONE)) /* Not testing a filter */ |
059ec3d9 PH |
4035 | { |
4036 | sender_address = originator_login; | |
4037 | sender_address_forced = FALSE; | |
4038 | sender_address_domain = 0; | |
4039 | } | |
4040 | } | |
4041 | ||
4042 | /* Remember whether an untrusted caller set the sender address */ | |
4043 | ||
4044 | sender_set_untrusted = sender_address != originator_login && !trusted_caller; | |
4045 | ||
4046 | /* Ensure that the sender address is fully qualified unless it is the empty | |
4047 | address, which indicates an error message, or doesn't exist (root caller, smtp | |
4048 | interface, no -f argument). */ | |
4049 | ||
4050 | if (sender_address != NULL && sender_address[0] != 0 && | |
4051 | sender_address_domain == 0) | |
4052 | sender_address = string_sprintf("%s@%s", local_part_quote(sender_address), | |
4053 | qualify_domain_sender); | |
4054 | ||
4055 | DEBUG(D_receive) debug_printf("sender address = %s\n", sender_address); | |
4056 | ||
4057 | /* Handle a request to verify a list of addresses, or test them for delivery. | |
4058 | This must follow the setting of the sender address, since routers can be | |
4059 | predicated upon the sender. If no arguments are given, read addresses from | |
4060 | stdin. Set debug_level to at least D_v to get full output for address testing. | |
4061 | */ | |
4062 | ||
4063 | if (verify_address_mode || address_test_mode) | |
4064 | { | |
4065 | int exit_value = 0; | |
4066 | int flags = vopt_qualify; | |
4067 | ||
4068 | if (verify_address_mode) | |
4069 | { | |
4070 | if (!verify_as_sender) flags |= vopt_is_recipient; | |
4071 | DEBUG(D_verify) debug_print_ids(US"Verifying:"); | |
4072 | } | |
4073 | ||
4074 | else | |
4075 | { | |
4076 | flags |= vopt_is_recipient; | |
4077 | debug_selector |= D_v; | |
4078 | debug_file = stderr; | |
4079 | debug_fd = fileno(debug_file); | |
4080 | DEBUG(D_verify) debug_print_ids(US"Address testing:"); | |
4081 | } | |
4082 | ||
4083 | if (recipients_arg < argc) | |
4084 | { | |
4085 | while (recipients_arg < argc) | |
4086 | { | |
4087 | uschar *s = argv[recipients_arg++]; | |
4088 | while (*s != 0) | |
4089 | { | |
4090 | BOOL finished = FALSE; | |
4091 | uschar *ss = parse_find_address_end(s, FALSE); | |
4092 | if (*ss == ',') *ss = 0; else finished = TRUE; | |
4093 | test_address(s, flags, &exit_value); | |
4094 | s = ss; | |
4095 | if (!finished) | |
4096 | while (*(++s) != 0 && (*s == ',' || isspace(*s))); | |
4097 | } | |
4098 | } | |
4099 | } | |
4100 | ||
4101 | else for (;;) | |
4102 | { | |
4103 | uschar *s = get_stdinput(NULL, NULL); | |
4104 | if (s == NULL) break; | |
4105 | test_address(s, flags, &exit_value); | |
4106 | } | |
4107 | ||
4108 | route_tidyup(); | |
4109 | exim_exit(exit_value); | |
4110 | } | |
4111 | ||
4112 | /* Handle expansion checking */ | |
4113 | ||
4114 | if (expansion_test) | |
4115 | { | |
4116 | if (recipients_arg < argc) | |
4117 | { | |
4118 | while (recipients_arg < argc) | |
4119 | { | |
4120 | uschar *s = argv[recipients_arg++]; | |
4121 | uschar *ss = expand_string(s); | |
4122 | if (ss == NULL) | |
4123 | printf ("Failed: %s\n", expand_string_message); | |
4124 | else printf("%s\n", CS ss); | |
4125 | } | |
4126 | } | |
4127 | ||
4128 | /* Read stdin */ | |
4129 | ||
4130 | else | |
4131 | { | |
4132 | char *(*fn_readline)(char *) = NULL; | |
4133 | char *(*fn_addhist)(char *) = NULL; | |
4134 | ||
4135 | #ifdef USE_READLINE | |
4136 | void *dlhandle = set_readline(&fn_readline, &fn_addhist); | |
4137 | #endif | |
4138 | ||
4139 | for (;;) | |
4140 | { | |
4141 | uschar *ss; | |
4142 | uschar *source = get_stdinput(fn_readline, fn_addhist); | |
4143 | if (source == NULL) break; | |
4144 | ss = expand_string(source); | |
4145 | if (ss == NULL) | |
4146 | printf ("Failed: %s\n", expand_string_message); | |
4147 | else printf("%s\n", CS ss); | |
4148 | } | |
4149 | ||
4150 | #ifdef USE_READLINE | |
4151 | if (dlhandle != NULL) dlclose(dlhandle); | |
4152 | #endif | |
4153 | } | |
4154 | ||
4155 | exim_exit(EXIT_SUCCESS); | |
4156 | } | |
4157 | ||
4158 | ||
4159 | /* The active host name is normally the primary host name, but it can be varied | |
4160 | for hosts that want to play several parts at once. We need to ensure that it is | |
4161 | set for host checking, and for receiving messages. */ | |
4162 | ||
4163 | smtp_active_hostname = primary_hostname; | |
4164 | if (raw_active_hostname != NULL) | |
4165 | { | |
4166 | uschar *nah = expand_string(raw_active_hostname); | |