X-Git-Url: https://git.exim.org/exim.git/blobdiff_plain/a5bd321b2f16ff323e3e268d59606e89b747a901..935ff400bc242e824ad2e1d2b5571fb9e611f923:/src/src/exim.c diff --git a/src/src/exim.c b/src/src/exim.c index 3ac7d8313..0b764e99a 100644 --- a/src/src/exim.c +++ b/src/src/exim.c @@ -1,4 +1,4 @@ -/* $Cambridge: exim/src/src/exim.c,v 1.41 2006/07/13 13:53:33 ph10 Exp $ */ +/* $Cambridge: exim/src/src/exim.c,v 1.48 2006/11/07 11:07:43 ph10 Exp $ */ /************************************************* * Exim - an Internet mail transport agent * @@ -980,6 +980,9 @@ fprintf(f, "Authenticators:"); #ifdef AUTH_CYRUS_SASL fprintf(f, " cyrus_sasl"); #endif +#ifdef AUTH_DOVECOT + fprintf(f, " dovecot"); +#endif #ifdef AUTH_PLAINTEXT fprintf(f, " plaintext"); #endif @@ -1174,7 +1177,7 @@ int size = 0; int ptr = 0; uschar *yield = NULL; -if (fn_readline == NULL) printf("> "); +if (fn_readline == NULL) { printf("> "); fflush(stdout); } for (i = 0;; i++) { @@ -1287,6 +1290,7 @@ BOOL more = TRUE; BOOL one_msg_action = FALSE; BOOL queue_only_set = FALSE; BOOL receiving_message = TRUE; +BOOL sender_ident_set = FALSE; BOOL unprivileged; BOOL removed_privilege = FALSE; BOOL verify_address_mode = FALSE; @@ -1296,6 +1300,7 @@ uschar *alias_arg = NULL; uschar *called_as = US""; uschar *start_queue_run_id = NULL; uschar *stop_queue_run_id = NULL; +uschar *expansion_test_message = NULL; uschar *ftest_domain = NULL; uschar *ftest_localpart = NULL; uschar *ftest_prefix = NULL; @@ -1676,10 +1681,21 @@ for (i = 1; i < argc; i++) else if (*argrest != 0) { badarg = TRUE; break; } } - /* -be: Run in expansion test mode */ + /* -be: Run in expansion test mode + -bem: Ditto, but read a message from a file first + */ else if (*argrest == 'e') + { expansion_test = checking = TRUE; + if (argrest[1] == 'm') + { + if (++i >= argc) { badarg = TRUE; break; } + expansion_test_message = argv[i]; + argrest++; + } + if (argrest[1] != 0) { badarg = TRUE; break; } + } /* -bF: Run system filter test */ @@ -2248,6 +2264,7 @@ for (i = 1; i < argc; i++) -Mmad mark all recipients delivered -Mmd mark recipients(s) delivered -Mes edit sender + -Mset load a message for use with -be -Mvb show body -Mvh show header -Mvl show log @@ -2285,6 +2302,11 @@ for (i = 1; i < argc; i++) one_msg_action = TRUE; } else if (Ustrcmp(argrest, "rm") == 0) msg_action = MSG_REMOVE; + else if (Ustrcmp(argrest, "set") == 0) + { + msg_action = MSG_LOAD; + one_msg_action = TRUE; + } else if (Ustrcmp(argrest, "t") == 0) msg_action = MSG_THAW; else if (Ustrcmp(argrest, "vb") == 0) { @@ -2520,7 +2542,11 @@ for (i = 1; i < argc; i++) /* -oMt: Set sender ident */ - else if (Ustrcmp(argrest, "Mt") == 0) sender_ident = argv[++i]; + else if (Ustrcmp(argrest, "Mt") == 0) + { + sender_ident_set = TRUE; + sender_ident = argv[++i]; + } /* Else a bad argument */ @@ -2878,13 +2904,14 @@ if (( ) || ( msg_action_arg > 0 && - (daemon_listen || queue_interval >= 0 || list_options || checking || - bi_option || test_retry_arg >= 0 || test_rewrite_arg >= 0) + (daemon_listen || queue_interval >= 0 || list_options || + (checking && msg_action != MSG_LOAD) || + bi_option || test_retry_arg >= 0 || test_rewrite_arg >= 0) ) || ( (daemon_listen || queue_interval >= 0) && (sender_address != NULL || list_options || list_queue || checking || - bi_option) + bi_option) ) || ( daemon_listen && queue_interval == 0 @@ -2909,6 +2936,10 @@ if (( ) || ( deliver_selectstring != NULL && queue_interval < 0 + ) || + ( + msg_action == MSG_LOAD && + (!expansion_test || expansion_test_message != NULL) ) ) { @@ -3647,12 +3678,12 @@ if (count_queue) exit(EXIT_SUCCESS); } -/* Handle actions on specific messages, except for the force delivery action, -which is done below. Some actions take a whole list of message ids, which -are known to continue up to the end of the arguments. Others take a single -message id and then operate on the recipients list. */ +/* Handle actions on specific messages, except for the force delivery and +message load actions, which are done below. Some actions take a whole list of +message ids, which are known to continue up to the end of the arguments. Others +take a single message id and then operate on the recipients list. */ -if (msg_action_arg > 0 && msg_action != MSG_DELIVER) +if (msg_action_arg > 0 && msg_action != MSG_DELIVER && msg_action != MSG_LOAD) { int yield = EXIT_SUCCESS; set_process_info("acting on specified messages"); @@ -3832,16 +3863,19 @@ if (list_options) /* Handle a request to deliver one or more messages that are already on the -queue. Values of msg_action other than MSG_DELIVER are dealt with above. This -is typically used for a small number when prodding by hand (when the option -forced_delivery will be set) or when re-execing to regain root privilege. -Each message delivery must happen in a separate process, so we fork a process -for each one, and run them sequentially so that debugging output doesn't get -intertwined, and to avoid spawning too many processes if a long list is given. -However, don't fork for the last one; this saves a process in the common case -when Exim is called to deliver just one message. */ - -if (msg_action_arg > 0) +queue. Values of msg_action other than MSG_DELIVER and MSG_LOAD are dealt with +above. MSG_LOAD is handled with -be (which is the only time it applies) below. + +Delivery of specific messages is typically used for a small number when +prodding by hand (when the option forced_delivery will be set) or when +re-execing to regain root privilege. Each message delivery must happen in a +separate process, so we fork a process for each one, and run them sequentially +so that debugging output doesn't get intertwined, and to avoid spawning too +many processes if a long list is given. However, don't fork for the last one; +this saves a process in the common case when Exim is called to deliver just one +message. */ + +if (msg_action_arg > 0 && msg_action != MSG_LOAD) { if (prod_requires_admin && !admin_user) { @@ -4055,12 +4089,14 @@ if ((sender_address == NULL && !smtp_input) || sender_local = TRUE; /* A trusted caller can supply authenticated_sender and authenticated_id - via -oMas and -oMai and if so, they will already be set. */ + via -oMas and -oMai and if so, they will already be set. Otherwise, force + defaults except when host checking. */ - if (authenticated_sender == NULL) + if (authenticated_sender == NULL && !host_checking) authenticated_sender = string_sprintf("%s@%s", originator_login, qualify_domain_sender); - if (authenticated_id == NULL) authenticated_id = originator_login; + if (authenticated_id == NULL && !host_checking) + authenticated_id = originator_login; } /* Trusted callers are always permitted to specify the sender address. @@ -4159,18 +4195,65 @@ if (verify_address_mode || address_test_mode) exim_exit(exit_value); } -/* Handle expansion checking */ +/* Handle expansion checking. Either expand items on the command line, or read +from stdin if there aren't any. If -Mset was specified, load the message so +that its variables can be used, but restrict this facility to admin users. +Otherwise, if -bem was used, read a message from stdin. */ if (expansion_test) { + if (msg_action_arg > 0 && msg_action == MSG_LOAD) + { + uschar spoolname[256]; /* Not big_buffer; used in spool_read_header() */ + if (!admin_user) + { + fprintf(stderr, "exim: permission denied\n"); + exit(EXIT_FAILURE); + } + message_id = argv[msg_action_arg]; + (void)string_format(spoolname, sizeof(spoolname), "%s-H", message_id); + if (!spool_open_datafile(message_id)) + printf ("Failed to load message datafile %s\n", message_id); + if (spool_read_header(spoolname, TRUE, FALSE) != spool_read_OK) + printf ("Failed to load message %s\n", message_id); + } + + /* Read a test message from a file. We fudge it up to be on stdin, saving + stdin itself for later reading of expansion strings. */ + + else if (expansion_test_message != NULL) + { + int save_stdin = dup(0); + int fd = Uopen(expansion_test_message, O_RDONLY, 0); + if (fd < 0) + { + fprintf(stderr, "exim: failed to open %s: %s\n", expansion_test_message, + strerror(errno)); + return EXIT_FAILURE; + } + (void) dup2(fd, 0); + filter_test = FTEST_USER; /* Fudge to make it look like filter test */ + message_ended = END_NOTENDED; + read_message_body(receive_msg(extract_recipients)); + message_linecount += body_linecount; + (void)dup2(save_stdin, 0); + (void)close(save_stdin); + clearerr(stdin); /* Required by Darwin */ + } + + /* Allow $recipients for this testing */ + + enable_dollar_recipients = TRUE; + + /* Expand command line items */ + if (recipients_arg < argc) { while (recipients_arg < argc) { uschar *s = argv[recipients_arg++]; uschar *ss = expand_string(s); - if (ss == NULL) - printf ("Failed: %s\n", expand_string_message); + if (ss == NULL) printf ("Failed: %s\n", expand_string_message); else printf("%s\n", CS ss); } } @@ -4202,6 +4285,14 @@ if (expansion_test) #endif } + /* The data file will be open after -Mset */ + + if (deliver_datafile >= 0) + { + (void)close(deliver_datafile); + deliver_datafile = -1; + } + exim_exit(EXIT_SUCCESS); } @@ -4225,20 +4316,24 @@ if (raw_active_hostname != NULL) } /* Handle host checking: this facility mocks up an incoming SMTP call from a -given IP address so that the blocking and relay configuration can be tested. An -RFC 1413 call is made only if we are running in the test harness and an -incoming interface and both ports are specified, because there is no TCP/IP -call to find the ident for. */ +given IP address so that the blocking and relay configuration can be tested. +Unless a sender_ident was set by -oMt, we discard it (the default is the +caller's login name). An RFC 1413 call is made only if we are running in the +test harness and an incoming interface and both ports are specified, because +there is no TCP/IP call to find the ident for. */ if (host_checking) { int x[4]; int size; - sender_ident = NULL; - if (running_in_test_harness && sender_host_port != 0 && - interface_address != NULL && interface_port != 0) - verify_get_ident(1413); + if (!sender_ident_set) + { + sender_ident = NULL; + if (running_in_test_harness && sender_host_port != 0 && + interface_address != NULL && interface_port != 0) + verify_get_ident(1413); + } /* In case the given address is a non-canonical IPv6 address, canonicize it. The code works for both IPv4 and IPv6, as it happens. */ @@ -4433,8 +4528,8 @@ if (smtp_input) else { - thismessage_size_limit = expand_string_integer(message_size_limit); - if (thismessage_size_limit < 0) + thismessage_size_limit = expand_string_integer(message_size_limit, TRUE); + if (expand_string_message != NULL) { if (thismessage_size_limit == -1) log_write(0, LOG_MAIN|LOG_PANIC_DIE, "failed to expand "