2
# $Cambridge: exim/exim-src/src/convert4r4.src,v 1.1 2004/10/07 10:39:01 ph10 Exp $
4
# This is a Perl script that reads an Exim run-time configuration file for
5
# Exim 3. It makes what changes it can for Exim 4, and also output commentary
6
# on what it has done, and on things it cannot do.
8
# It is assumed that the input is a valid Exim 3 configuration file.
11
# These are lists of main options which are abolished in Exim 4.
12
# The first contains options that are used to construct new options.
16
"auth_over_tls_hosts",
18
"headers_check_syntax",
19
"headers_checks_fail",
20
"headers_sender_verify",
21
"headers_sender_verify_errmsg",
23
"host_auth_accept_relay",
24
"host_reject_recipients",
26
"local_domains_include_host",
27
"local_domains_include_host_literals",
33
"log_received_sender",
34
"log_received_recipients",
36
"log_sender_on_delivery",
37
"log_smtp_confirmation",
38
"log_smtp_connections",
39
"log_smtp_syntax_errors",
41
"log_queue_run_level",
44
"rbl_reject_recipients",
46
"receiver_verify_addresses",
47
"receiver_verify_hosts",
48
"receiver_verify_senders",
49
"recipients_reject_except",
50
"recipients_reject_except_senders",
52
"relay_domains_include_local_mx",
53
"sender_address_relay",
54
"sender_address_relay_hosts",
55
"sender_reject_recipients",
57
"sender_verify_hosts_callback",
58
"sender_verify_callback_domains",
59
"sender_verify_callback_timeout",
60
"sender_verify_hosts",
64
"tls_host_accept_relay",
71
# The second contains options that are completely abolished and have
74
@abolished_options = (
80
"log_refused_recipients",
81
"message_size_limit_count_recipients",
84
"receiver_try_verify",
86
"relay_match_host_or_sender",
88
"sender_verify_batch",
89
"sender_verify_fixup",
90
"sender_verify_reject",
91
"sender_verify_max_retry_rate",
94
# This is a list of options that are not otherwise handled, but which
95
# contain domain or host lists that have to be processed so that any
96
# regular expressions are marked "not for expansion".
99
"dns_again_means_nonexist",
101
"hosts_treat_as_local",
102
"percent_hack_domains",
103
"queue_smtp_domains",
104
"helo_accept_junk_hosts",
106
"ignore_fromline_hosts",
108
"sender_unqualified_hosts",
109
"smtp_reserve_hosts",
110
"tls_advertise_hosts",
116
##################################################
117
# Output problem rubric once #
118
##################################################
121
return if $rubric_output;
124
"** The following comments describe problems that have been encountered\n" .
125
" while converting an Exim 3 runtime file for Exim 4. More detail can\n" .
126
" be found in the file doc/Exim4.upgrade.\n";
130
##################################################
132
##################################################
137
return "comment" if $line =~ /^\s*(#|$)/;
138
return "end" if $line =~ /^\s*end\s*$/i;
140
# Macros are recognized only in the first section of the file.
142
return "macro" if $prefix eq "" && $line =~ /^\s*[A-Z]/;
144
# In retry and rewrite sections, the type is always "other"
146
return "other" if $prefix eq "=retry" || $prefix eq "=rewrite";
148
# Pick out the name at the start and the rest of the line (into global
149
# variables) and return whether the start of a driver or not.
151
($hide,$name,$rest) = $line =~ /^\s*(hide\s+|)([a-z0-9_]+)\s*(.*?)\s*$/;
153
# If $rest begins with a colon, this is a driver name
155
return "driver" if $rest =~ /^:/;
157
# If $rest begins with an = the value of the option is given explicitly;
158
# remove the = from the start. Turn "yes"/"no" into "true"/"false".
163
$rest = "true" if $rest eq "yes";
164
$rest = "false" if $rest eq "no";
167
# Otherwise we have a boolean option. Set up a "true"/"false" value.
171
if ($name =~ /^not?_/) # Recognize "no_" or "not_"
187
##################################################
188
# Negate a list of things #
189
##################################################
191
# Can be tricky, because there may be comment lines in the list.
192
# Also, lists may have different delimiters.
199
return $list if ! defined $list;
201
($list) = $list =~ /^"?(.*?)"?\s*$/s; # Remove surrounding quotes
202
$list =~ s/\\\s*\n\s*//g; # Remove continuation markers
204
if ($list =~ /^(\s*<(\S)\s*)(.*)/s)
212
$list =~ s/\Q$delim$delim/>%%%%</g;
213
@split = split /\s*\Q$delim\E\s*/s, $list;
215
foreach $item (@split)
217
$item =~ s/>%%%%</$delim$delim/g;
219
if ($item =~ /^\s*#/)
221
$item =~ s/((?:^\s*#[^\n]*\n)+\s*)/$1! /mg;
222
$item =~ s/!\s*!//sg;
226
if ($item =~ /^\s*!(.*)/)
229
{ $item = "! " . $item; }
233
$" = " $delim \\\n ";
234
$leadin .= " " if $leadin !~ /(^|\s)$/;
235
return "$leadin@split";
240
##################################################
241
# Prevent regex expansion in a list of things #
242
##################################################
244
# Can be tricky, because there may be comment lines in the list.
245
# Also, lists may have different delimiters.
247
sub no_expand_regex {
252
return $list if ! defined $list;
254
$delim = $_[1] if (defined $_[1]);
256
my($is_route_list) = $delim eq ";";
258
($list) = $list =~ /^"?(.*?)"?\s*$/s; # Remove surrounding quotes
259
$list =~ s/\\\s*\n\s*//g; # Remove continuation markers
261
if ($list =~ /^(\s*<(\S)\s*)(.*)/s)
269
$list =~ s/\Q$delim$delim/>%%%%</g;
270
@split = split /\s*\Q$delim\E\s*/s, $list;
273
foreach $item (@split)
275
$item =~ s/>%%%%</$delim$delim/g;
278
# Fudge for route_list items
282
$item = "\\N$item"; # Only one item ...
286
$item = "\\N$item\\N";
292
"#!!# Regular expressions enclosed in \\N...\\N to avoid expansion\n"
295
$" = " $delim \\\n ";
296
$leadin .= " " if $leadin !~ /(^|\s)$/;
297
return "$leadin@split";
302
##################################################
303
# Sort out lookups in an address list #
304
##################################################
306
# Can be tricky, because there may be comment lines in the list.
307
# Also, lists may have different delimiters.
309
sub sort_address_list {
316
return $list if ! defined $list;
318
if ($list =~ /^"(.*?)"\s*$/s) # Remove surrounding quotes
324
$list =~ s/\\\s*\n\s*//g; # Remove continuation markers
326
if ($list =~ /^(\s*<(\S)\s*)(.*)/s)
334
$list =~ s/\Q$delim$delim/>%%%%</g;
335
@split = split /\s*\Q$delim\E\s*/s, $list;
337
foreach $item (@split)
339
$item =~ s/>%%%%</$delim$delim/g;
340
if ($item =~ /^\s*(?:partial-)?(\w+;.*)$/)
343
if ($lookup =~ /^lsearch|^dbm|^cdb|^nis[^p]/)
347
"** The Exim 3 \"$name\" option specifies an address\n" .
348
" list that includes the item\n\n" .
350
" In Exim 4 address lists, single-key lookups without a local part just\n" .
351
" look up the complete address. They don't also try the domain, as\n" .
352
" happened in Exim 3. The item has been rewritten as two items to make\n" .
353
" it behave in the same way as Exim 3, but you should check to see if\n" .
354
" this is actually what you want.\n";
356
$item = "*\@$item $delim $lookup";
361
$" = " $delim \\\n ";
362
$leadin .= " " if $leadin !~ /(^|\s)$/;
364
return $quoted? "\"$leadin@split\"" : "$leadin@split";
369
##################################################
370
# Quote a string against expansion #
371
##################################################
373
# Used for setting up new "domains" options
378
$s =~ s/\\(?!\s*\n)/\\\\/sg;
384
##################################################
385
# Dequote an option string #
386
##################################################
388
# If the original list is not quoted, do nothing.
389
# If it is quoted, just get rid of the quotes.
393
$s =~ s/^"(.*)"$/$1/s;
398
##################################################
399
# Quote/dequote an option string #
400
##################################################
402
# If the original list is not quoted, quote it against expansion.
403
# If it is quoted, just get rid of the quotes. Also, indent any
408
$s = ($s =~ /^"(.*)"$/s)? $1 : &expquote($s);
410
$s =~ s/\n\s{11,}/\n /g;
415
##################################################
416
# Handle abolished driver options #
417
##################################################
420
my($hash) = shift @_;
421
my($name) = shift @_;
424
if (defined $$hash{$abolished})
428
"** $name used the \"$abolished\" option, which no\n".
429
" longer exists. The option has been removed.\n";
430
print STDOUT "#!!# $abolished option removed\n";
431
delete $$hash{$abolished};
438
##################################################
439
# Handle renamed driver options #
440
##################################################
443
my($hash,$old,$new) = @_;
444
if (defined $$hash{$old})
446
print STDOUT "#!!# $old renamed $new\n";
447
$$hash{$new} = $$hash{$old};
454
##################################################
455
# Comment on user names in require_files #
456
##################################################
459
my($string, $name) = @_;
461
$string =~ s/::/[[[]]]/g;
462
my(@list) = split /:/, $string;
467
if ($item =~ /^\s*[\w,]+\s*$/)
473
"** A setting of require_files in the $name contains\n" .
474
" what appears to be a user name ('$item'). The ability to check files\n" .
475
" as a specific user is done differently in Exim 4. In fact, because the\n" .
476
" routers run as root, you may not need this at all.\n"
482
##################################################
483
# Handle current and home directory #
484
##################################################
486
sub handle_current_and_home_directory {
487
my($hash,$driver,$name) = @_;
489
for ("current_directory", "home_directory")
491
if (defined $$hash{$_} && $$hash{$_} eq "check_local_user")
493
my($article) = (substr($driver, 0, 1) eq "a")? "an" : "a";
496
"** The Exim 3 configuration contains $article '$driver' director called\n" .
497
" '$name', which set '$_' to the special value\n" .
498
" 'check_local_user'. This facility has been abolished in Exim 4 because\n" .
499
" it is no longer necessary. The setting has therefore been omitted. See\n" .
505
&renamed($hash, $_, "transport_$_");
512
##################################################
513
# Handle batch/bsmtp for appendfile/pipe #
514
##################################################
516
sub handle_batch_and_bsmtp{
519
if (defined $$hash{"bsmtp"})
521
if ($$hash{"bsmtp"} ne "none")
523
$$hash{"use_bsmtp"} = "true";
524
$$hash{"message_prefix"} = "\"HELO \$primary_host_name\\n\""
525
if defined $$hash{"bsmtp_helo"} && $$hash{"bsmtp_helo"} eq "true";
528
if ($$hash{"bsmtp"} eq "one")
530
delete $$hash{"batch"};
534
$$hash{"batch"} = $$hash{"bsmtp"};
537
delete $$hash{"bsmtp"};
538
delete $$hash{"bsmtp_helo"};
541
if (defined $$hash{"batch"} && $$hash{"batch"} ne "none")
543
$$hash{"batch_max"} = "100" if !defined $$hash{"batch_max"};
544
$$hash{"batch_id"} = "\$domain" if $$hash{"batch"} eq "domain";
548
$$hash{"batch_max"} = "1" if defined $$hash{"batch_max"};
550
delete $$hash{"batch"};
555
##################################################
556
# Output one option #
557
##################################################
560
my($hash, $key, $no_expand) = @_;
561
my($data) = $$hash{$key};
563
print STDOUT "hide " if defined $$hash{"$key-hide"};
565
# Output booleans in the form that doesn't use "="
569
print STDOUT "$key\n";
571
elsif ($data eq "false")
573
print STDOUT "no_$key\n";
579
printf STDOUT ("$key = %s\n", &no_expand_regex($data));
583
print STDOUT "$key = $data\n";
590
##################################################
591
# Output the options for one driver #
592
##################################################
594
# Put the "driver" option first
598
print STDOUT " driver = $$hash{'driver'}\n";
599
foreach $key (sort keys %$hash)
601
next if $key eq "driver" || $key =~ /-hide$/;
603
&outopt($hash, $key, 0);
609
##################################################
610
# Output a rewrite or a retry line #
611
##################################################
613
# These lines start with patterns which are now always expanded. If the
614
# pattern is a regex, arrange for it not to expand.
616
sub print_no_expand {
624
"** You have a retry or rewrite pattern that is a regular expression. Because\n" .
625
" these patterns are now always expanded, you need to be sure that the\n" .
626
" special characters in the regex are not interpreted by the expander.\n" .
627
" \\N has been inserted at the start of the regex to prevent the rest of\n" .
628
" it from being expanded.\n";
638
##################################################
639
# Test a boolean main option #
640
##################################################
642
# This just saves a lot of typing
645
return defined $main{$_[0]} && $main{$_[0]} eq "true";
650
##################################################
652
##################################################
654
print STDERR "Runtime configuration file converter for Exim release 4.\n";
656
$transport_start = $director_start = $router_start = $retry_start
657
= $rewrite_start = $auth_start = 999999;
666
$add_caseful_local_part = 0;
667
$done_dns_check_names = 0;
669
$queue_only_load_was_present = 0;
670
$deliver_queue_load_max_was_present = 0;
672
# Read the entire file into an array
677
# Remove the standard comment that appears at the end of the default
679
if ($clen > 0 && $c[$clen-1] =~ /^#\s*End of Exim configuration file\s*/i)
685
# The first pass over the input fishes out all the options settings in the
686
# main, transport, director, and router sections, and places their values in
687
# associative arrays. It also notes the starting position of all the sections.
693
for ($i = 0; $i < $clen; $i++)
695
# Change references to +allow_unknown and +warn_unknown into +include_unknown
697
if ($c[$i] =~ /\+(?:allow|warn)_unknown/)
703
"** You have used '+allow_unknown' or '+warn_unknown' in a configuration\n" .
704
" option. This has been converted to '+include_unknown', but the action\n" .
705
" is different in Exim 4, so you should review all the relevant options.\n";
708
$c[$i] =~ s/\+(?:allow|warn)_unknown/+include_unknown/g;
711
# Any reference to $errmsg_recipient is changed to $bounce_recipient
713
if ($c[$i] =~ /\$errmsg_recipient/)
719
"** References to \$errmsg_recipient have been changed to \$bounce_recipient\n";
722
$c[$i] =~ s/\$errmsg_recipient/\$bounce_recipient/g;
726
# Analyse the type of line
728
$type = &checkline($c[$i]);
729
next if $type eq "comment";
731
# Output a warning if $key is used
733
if ($c[$i] =~ /\$key/ && !$key_output)
737
"** You have used '\$key' in a configuration option. This variable does not\n" .
738
" exist in Exim 4. Instead, the value you need for your lookup will be\n" .
739
" in one of the other variables such as '\$domain' or '\$host'. You will\n" .
740
" need to edit the new configuration to sort this out.\n";
744
# Save macro definitions so we can output them first; must handle
747
if ($type eq "macro")
749
$macro_output .= "$c[$i++]\n" while $c[$i] =~ /\\\s*$|^\s*#/;
750
$macro_output .= "$c[$i]\n";
753
# Handle end of section
755
elsif ($type eq "end")
757
if ($prefix eq "=rewrite")
760
$auth_start = $i + 1;
763
elsif ($prefix eq "=retry")
765
$prefix = "=rewrite";
766
$rewrite_start = $i + 1;
768
elsif ($prefix eq "r.")
771
$retry_start = $i + 1;
773
elsif ($prefix eq "d.")
776
$router_start = $i + 1;
778
elsif ($prefix eq "t.")
781
$director_start = $i + 1;
783
elsif ($prefix eq "")
786
$transport_start = $i + 1;
790
# Handle start of a new director, router or transport driver
792
elsif ($type eq "driver" && $prefix !~ /^=/)
795
if (defined $driverlist{"$prefix$name"})
797
die "*** There are two drivers with the name \"$name\"\n";
799
$driverlist{"$prefix$name"} = $hash;
800
$first_director = $name if !defined $first_director && $prefix eq "d.";
803
# Handle definition of an option; we must pull in any continuation
804
# strings, and save the value in the current hash. Note if the option
807
elsif ($type eq "option")
811
while ($i < $clen - 1 && ($rest =~ /\\\s*$/s || $nextline =~ /^\s*#/))
813
$nextline = $c[++$i];
814
$rest .= "\n$nextline";
817
$$hash{$name} = $rest;
818
$$hash{"$name-hide"} = 1 if $hide ne "";
823
# Generate the new configuration. Start with a warning rubric.
825
print STDOUT "#!!# This file is output from the convert4r4 script, which tries\n";
826
print STDOUT "#!!# to convert Exim 3 configurations into Exim 4 configurations.\n";
827
print STDOUT "#!!# However, it is not perfect, especially with non-simple\n";
828
print STDOUT "#!!# configurations. You must check it before running it.\n";
831
# Output the macro definitions
833
if ($macro_output ne "")
835
print STDOUT "#!!# All macro definitions have been gathered here to ensure\n";
836
print STDOUT "#!!# they precede any references to them.\n\n";
837
print STDOUT "$macro_output\n";
840
# Output some default pointers to ACLs for RCPT and DATA time. If no Exim 3
841
# options that apply are set, non-restricting ACLs are generated.
843
print STDOUT "#!!# These options specify the Access Control Lists (ACLs) that\n";
844
print STDOUT "#!!# are used for incoming SMTP messages - after the RCPT and DATA\n";
845
print STDOUT "#!!# commands, respectively.\n\n";
847
print STDOUT "acl_smtp_rcpt = check_recipient\n";
848
print STDOUT "acl_smtp_data = check_message\n\n";
850
if (defined $main{"auth_over_tls_hosts"})
852
print STDOUT "#!!# This option specifies the Access Control List (ACL) that\n";
853
print STDOUT "#!!# is used after an AUTH command.\n\n";
854
print STDOUT "acl_smtp_auth = check_auth\n\n";
857
if (&bool("smtp_verify") ||
858
defined $main{"smtp_etrn_hosts"} ||
859
defined $main{"smtp_expn_hosts"})
861
print STDOUT "#!!# These options specify the Access Control Lists (ACLs) that\n";
862
print STDOUT "#!!# are used to control the ETRN, EXPN, and VRFY commands.\n";
863
print STDOUT "#!!# Where no ACL is defined, the command is locked out.\n\n";
865
print STDOUT "acl_smtp_etrn = check_etrn\n" if defined $main{"smtp_etrn_hosts"};
866
print STDOUT "acl_smtp_expn = check_expn\n" if defined $main{"smtp_expn_hosts"};
867
print STDOUT "acl_smtp_vrfy = check_vrfy\n" if &bool("smtp_verify");
871
# If local_domains was set, get its value; otherwise set to "@". Add into it
872
# appropriate magic for local_domains_include_host[_literals].
874
$local_domains = (defined $main{"local_domains"})? $main{"local_domains"} : "@";
877
if ($local_domains =~ /^\s*<(.)\s*(.*)/s)
883
$local_domains = "\@[] $ldsep " . $local_domains
884
if defined $main{"local_domains_include_host_literals"} &&
885
$main{"local_domains_include_host_literals"} eq "true";
887
$local_domains = "\@ $ldsep " . $local_domains
888
if defined $main{"local_domains_include_host"} &&
889
$main{"local_domains_include_host"} eq "true";
891
$local_domains = "<$ldsep " . $local_domains if $ldsep ne ":";
893
# Output a domain list setting for these domains, provided something is defined
895
if ($local_domains !~ /^\s*$/)
897
print STDOUT "#!!# This setting defines a named domain list called\n";
898
print STDOUT "#!!# local_domains, created from the old options that\n";
899
print STDOUT "#!!# referred to local domains. It will be referenced\n";
900
print STDOUT "#!!# later on by the syntax \"+local_domains\".\n";
901
print STDOUT "#!!# Other domain and host lists may follow.\n\n";
903
printf STDOUT ("domainlist local_domains = %s\n\n",
904
&no_expand_regex($local_domains));
907
$relay_domains = (defined $main{"relay_domains"})? $main{"relay_domains"} : "";
910
if ($relay_domains =~ /^\s*<(.)\s*(.*)/s)
915
if (defined $main{"relay_domains_include_local_mx"})
917
$relay_domains .= ($relay_domains =~ /^\s*$/)? "\@mx_any" :
921
printf STDOUT ("domainlist relay_domains = %s\n",
922
&no_expand_regex($relay_domains))
923
if $relay_domains !~ /^\s*$/;
926
# If ignore_errmsg_errors is set, we are going to force 0s as the value
927
# for ignore_errmsg_errors_after, so arrange to skip any other value.
929
push @skipped_options, "ignore_errmsg_errors_after"
930
if &bool("ignore_errmsg_errors");
933
# If rbl_domains is set, split it up and generate six lists:
934
# rbl_warn_domains, rbl_warn_domains_skiprelay
935
# rbl_reject_domains, rbl_reject_domains_skiprelay
936
# rbl_accept_domains, rbl_accept_domains_skiprelay
938
if (defined $main{"rbl_domains"})
940
my($s) = &unquote($main{"rbl_domains"});
941
$s =~ s/\s*\\\s*\n\s*/ /g;
942
my(@list) = split /\s*:\s*/, $s;
946
my(@sublist) = split /\//, $d;
947
my($name) = shift @sublist;
949
if (defined $main{"rbl_reject_recipients"})
951
$warn = $main{"rbl_reject_recipients"} ne "true";
954
foreach $o (@sublist)
956
$warn = 1 if $o eq "warn";
957
$warn = 0 if $o eq "reject";
958
$warn = 2 if $o eq "accept";
959
$skiprelay = 1 if $o eq "skiprelay";
966
$rbl_reject_skiprelay .= ((defined $rbl_reject_skiprelay)? ":":"").$name;
970
$rbl_warn_skiprelay .= ((defined $rbl_warn_skiprelay)? ":":"").$name;
974
$rbl_accept_skiprelay .= ((defined $rbl_accept_skiprelay)? ":":"").$name;
981
$rbl_reject_domains .= ((defined $rbl_reject_domains)? ":":"").$name;
985
$rbl_warn_domains .= ((defined $rbl_warn_domains)? ":":"").$name;
989
$rbl_accept_domains .= ((defined $rbl_accept_domains)? ":":"").$name;
996
# Output host list settings
998
printf STDOUT ("hostlist auth_hosts = %s\n",
999
&no_expand_regex($main{"auth_hosts"}))
1000
if defined $main{"auth_hosts"};
1001
printf STDOUT ("hostlist rbl_hosts = %s\n",
1002
&no_expand_regex($main{"rbl_hosts"}))
1003
if defined $main{"rbl_hosts"};
1004
printf STDOUT ("hostlist relay_hosts = %s\n",
1005
&no_expand_regex($main{"host_accept_relay"}))
1006
if defined $main{"host_accept_relay"};
1007
printf STDOUT ("hostlist auth_relay_hosts = %s\n",
1008
&no_expand_regex($main{"host_auth_accept_relay"}))
1009
if defined $main{"host_auth_accept_relay"};
1011
printf STDOUT ("hostlist auth_over_tls_hosts = %s\n",
1012
&no_expand_regex($main{"auth_over_tls_hosts"}))
1013
if defined $main{"auth_over_tls_hosts"};
1014
printf STDOUT ("hostlist tls_hosts = %s\n",
1015
&no_expand_regex($main{"tls_hosts"}))
1016
if defined $main{"tls_hosts"};
1017
printf STDOUT ("hostlist tls_relay_hosts = %s\n",
1018
&no_expand_regex($main{"tls_host_accept_relay"}))
1019
if defined $main{"tls_host_accept_relay"};
1024
# Convert various logging options
1029
if (defined $main{"log_level"})
1031
my($level) = $main{"log_level"};
1032
$log_selector .= "$sep -retry_defer$sep -skip_delivery" if $level < 5;
1033
$log_selector .= "$sep -lost_incoming_connection$sep -smtp_syntax_error" .
1034
"$sep -delay_delivery" if $level < 4;
1035
$log_selector .= "$sep -size_reject" if $level < 2;
1038
$log_selector .= "$sep -queue_run"
1039
if defined $main{"log_queue_run_level"} &&
1040
defined $main{"log_level"} &&
1041
$main{"log_queue_run_level"} > $main{"log_level"};
1043
$log_selector .= "$sep +address_rewrite" if &bool("log_rewrites");
1044
$log_selector .= "$sep +all_parents" if &bool("log_all_parents");
1045
$log_selector .= "$sep +arguments" if &bool("log_arguments");
1046
$log_selector .= "$sep +incoming_port" if &bool("log_incoming_port");
1047
$log_selector .= "$sep +incoming_interface" if &bool("log_interface");
1048
$log_selector .= "$sep +received_sender" if &bool("log_received_sender");
1049
$log_selector .= "$sep +received_recipients" if &bool("log_received_recipients");
1050
$log_selector .= "$sep +sender_on_delivery" if &bool("log_sender_on_delivery");
1051
$log_selector .= "$sep +smtp_confirmation" if &bool("log_smtp_confirmation");
1052
$log_selector .= "$sep +smtp_connection" if &bool("log_smtp_connections");
1053
$log_selector .= "$sep +smtp_syntax_error" if &bool("log_smtp_syntax_errors");
1054
$log_selector .= "$sep +subject" if &bool("log_subject");
1055
$log_selector .= "$sep +tls_cipher" if &bool("tls_log_cipher");
1056
$log_selector .= "$sep +tls_peerdn" if &bool("tls_log_peerdn");
1059
if ($log_selector ne "")
1061
print STDOUT "#!!# All previous logging options are combined into a single\n"
1062
. "#!!# option in Exim 4. This setting is an approximation to\n"
1063
. "#!!# the previous state - some logging has changed.\n\n";
1064
print STDOUT "log_selector = $log_selector\n\n";
1067
# If deliver_load_max is set, replace it with queue_only_load (taking the
1068
# lower value if both set) and also set deliver_queue_load_max if it is
1069
# not already set. When scanning for output, deliver_load_max is skipped.
1071
if (defined $main{"deliver_load_max"})
1075
"** deliver_load_max is abolished in Exim 4.\n";
1077
if (defined $main{"queue_only_load"})
1079
$queue_only_load_was_present = 1;
1080
if ($main{"queue_only_load"} < $main{"deliver_load_max"})
1083
" As queue_only_load was set lower, deliver_load_max is just removed.\n";
1088
" As queue_only_load was set higher, it's value has been replaced by\n" .
1089
" the value of deliver_load_max.\n";
1090
$main{"queue_only_load"} = $main{"deliver_load_max"};
1096
" queue_only_load has been set to the load value.\n";
1097
$main{"queue_only_load"} = $main{"deliver_load_max"};
1100
if (!defined $main{"deliver_queue_load_max"})
1103
" deliver_queue_load_max has been set to the value of queue_only_load.\n";
1104
$main{"deliver_queue_load_max"} = $main{"queue_only_load"};
1108
$deliver_queue_load_max_was_present = 1;
1113
# Now we scan through the various parts of the file again, making changes
1116
# -------- The main configuration --------
1119
MainLine: for ($i = 0; $i < $clen; $i++)
1122
$type = &checkline($c[$i]);
1123
last if $type eq "end";
1125
if ($type eq "macro")
1127
$i++ while $c[$i] =~ /\\\s*$|^\s*#/;
1131
if ($type eq "comment") { print STDOUT "$c[$i]\n"; next; }
1133
# Collect any continuation lines for an option setting
1135
while ($rest =~ /\\\s*$/s || $nextline =~ /^\s*#/)
1137
$nextline = $c[++$i];
1138
$rest .= "\n$nextline";
1143
# Deal with main options that are skipped (they are used in other
1144
# options in other places).
1146
for $skipped (@skipped_options)
1148
next MainLine if $name eq $skipped;
1151
# Deal with main options that are totally abolished
1153
for $abolished (@abolished_options)
1155
if ($name eq $abolished)
1159
"** The $name option no longer exists, and has no equivalent\n" .
1165
# There is a special case for rbl_warn_header
1167
if ($name eq "rbl_warn_header")
1171
"** The $name option no longer exists. In Exim 4 you can achieve the\n" .
1172
" effect by adding a suitable \"message\" statement in the ACL.\n";
1175
# There is a special case for sender_reject and host_reject
1177
elsif ($name eq "sender_reject" || $name eq "host_reject")
1181
"** The $name option no longer exists. Its data has been used in\n" .
1182
" an Access Control List as if it were in ${name}_recipients.\n";
1185
# And a special message for prohibition_message
1187
elsif ($name eq "prohibition_message")
1191
"** The prohibition_message option no longer exists. The facility is\n" .
1192
" provided in a different way in Exim 4, via the \"message\" keyword\n" .
1193
" in Access Control Lists. It isn't possible to do an automatic conversion,\n" .
1194
" so the value of prohibition_message has been ignored. You will have to\n" .
1195
" modify the ACLs if you want to reinstate the feature.\n";
1198
# auth_always_advertise gets converted to auth_advertise_hosts
1200
elsif ($name eq "auth_always_advertise")
1202
print STDOUT "#!!# auth_always_advertise converted to auth_advertise_hosts\n";
1203
if (&bool("auth_always_advertise"))
1205
print STDOUT "auth_advertise_hosts = *\n";
1210
print STDOUT "auth_advertise_hosts =";
1211
if (defined $main{"auth_hosts"})
1213
print STDOUT "$sep +auth_hosts";
1216
if (defined $main{"host_accept_relay"})
1218
print STDOUT "$sep !+relay_hosts";
1221
if (defined $main{"host_auth_accept_relay"})
1223
print STDOUT "$sep +auth_relay_hosts";
1229
# Deal with main options that have to be rewritten
1231
elsif ($name eq "accept_timeout")
1233
print STDOUT "#!!# accept_timeout renamed receive_timeout\n";
1234
print STDOUT "receive_timeout = $rest\n";
1237
elsif ($name eq "collapse_source_routes")
1239
print STDOUT "#!!# collapse_source_routes removed\n";
1240
print STDOUT "#!!# It has been a no-op since 3.10.\n";
1243
elsif ($name eq "daemon_smtp_service")
1245
print STDOUT "#!!# daemon_smtp_service renamed daemon_smtp_port\n";
1246
print STDOUT "daemon_smtp_port = $rest\n";
1249
elsif ($name eq "dns_check_names" || $name eq "dns_check_names_pattern")
1251
if (!$done_dns_check_names)
1253
if (&bool("dns_check_names"))
1255
if (defined $main{"dns_check_names_pattern"})
1257
&outopt(\%main, "dns_check_names_pattern", 0);
1263
print STDOUT "#!!# dns_check_names has been abolished\n";
1264
print STDOUT "#!!# setting dns_check_pattern empty to turn off check\n";
1265
print STDOUT "dns_check_names_pattern =\n";
1268
$done_dns_check_names = 1;
1272
elsif ($name eq "deliver_load_max")
1274
print STDOUT "deliver_queue_load_max = $main{'deliver_queue_load_max'}\n"
1275
if !$deliver_queue_load_max_was_present;
1276
print STDOUT "queue_only_load = $main{'queue_only_load'}\n"
1277
if !$queue_only_load_was_present;
1280
elsif ($name eq "errmsg_file")
1282
print STDOUT "#!!# errmsg_file renamed bounce_message_file\n";
1283
print STDOUT "bounce_message_file = $rest\n";
1286
elsif ($name eq "errmsg_text")
1288
print STDOUT "#!!# errmsg_text renamed bounce_message_text\n";
1289
print STDOUT "bounce_message_text = $rest\n";
1292
elsif ($name eq "forbid_domain_literals")
1294
print STDOUT "#!!# forbid_domain_literals replaced by allow_domain_literals\n";
1295
print STDOUT "allow_domain_literals = ",
1296
&bool("forbid_domain_literals")? "false" : "true", "\n";
1299
elsif ($name eq "freeze_tell_mailmaster")
1301
print STDOUT "#!!# freeze_tell_mailmaster replaced by freeze_tell\n";
1302
if (&bool("freeze_tell_mailmaster"))
1304
print STDOUT "freeze_tell = ",
1305
((defined $main{"errors_address"})?
1306
$main{"errors_address"} : "postmaster"), "\n";
1310
print STDOUT "#!!# freeze_tell is unset by default\n";
1314
elsif ($name eq "helo_verify")
1316
print STDOUT "#!!# helo_verify renamed helo_verify_hosts\n";
1317
printf STDOUT ("helo_verify_hosts = %s\n", &no_expand_regex($rest));
1320
elsif ($name eq "ignore_errmsg_errors")
1322
print STDOUT "ignore_bounce_errors_after = 0s\n";
1325
elsif ($name eq "ignore_errmsg_errors_after")
1327
print STDOUT "#!!# ignore_errmsg_errors_after renamed ignore_bounce_errors_after\n";
1328
print STDOUT "ignore_bounce_errors_after = $rest\n";
1331
elsif ($name eq "ipv4_address_lookup" || $name eq "dns_ipv4_lookup")
1333
print STDOUT "#!!# $name changed to dns_ipv4_lookup\n"
1334
if $name eq "ipv4_address_lookup";
1335
print STDOUT "#!!# dns_ipv4_lookup is now a domain list\n";
1338
print STDOUT "dns_ipv4_lookup = *\n";
1342
print STDOUT "#!!# default for dns_ipv4_lookup is unset\n";
1346
elsif ($name eq "locally_caseless")
1348
print STDOUT "#!!# locally_caseless removed\n";
1349
print STDOUT "#!!# caseful_local_part will be added to ex-directors\n";
1350
$add_caseful_local_part = 1;
1353
elsif ($name eq "message_filter_directory2_transport")
1355
print STDOUT "#!!# message_filter_directory2_transport removed\n";
1358
elsif ($name =~ /^message_filter(.*)/)
1360
print STDOUT "#!!# $name renamed system_filter$1\n";
1361
print STDOUT "system_filter$1 = $rest\n";
1364
elsif ($name eq "queue_remote_domains")
1366
print STDOUT "#!!# queue_remote_domains renamed queue_domains\n";
1367
printf STDOUT ("queue_domains = %s\n", &no_expand_regex($rest));
1370
elsif ($name eq "receiver_unqualified_hosts")
1372
print STDOUT "#!!# receiver_unqualified_hosts renamed recipient_unqualified_hosts\n";
1373
printf STDOUT ("recipient_unqualified_hosts = %s\n",
1374
&no_expand_regex($rest));
1377
elsif ($name eq "remote_sort")
1379
print STDOUT "#!!# remote_sort renamed remote_sort_domains\n";
1380
printf STDOUT ("remote_sort_domains = %s\n", &no_expand_regex($rest));
1383
elsif ($name eq "security")
1385
if ($rest eq "unprivileged")
1387
print STDOUT "#!!# security=unprivileged changed to deliver_drop_privilege\n";
1388
print STDOUT "deliver_drop_privilege\n";
1394
"** The 'security' option no longer exists.\n";
1398
elsif ($name eq "timestamps_utc")
1400
print STDOUT "#!!# timestamps_utc changed to use timezone\n";
1401
print STDOUT "timezone = utc\n";
1404
elsif ($name eq "untrusted_set_sender")
1406
print STDOUT "#!!# untrusted_set_sender is now a list of what can be set\n";
1407
print STDOUT "#!!# The default is an empty list.\n";
1408
if (&bool("untrusted_set_sender"))
1410
print STDOUT "untrusted_set_sender = *\n";
1414
elsif ($name eq "warnmsg_file")
1416
print STDOUT "#!!# warnmsg_file renamed warn_message_file\n";
1417
print STDOUT "warn_message_file = $rest\n";
1420
# Remaining options just get copied unless they are one of those that's
1421
# a list where any regular expressions have to be escaped.
1426
foreach $o (@list_options)
1434
&outopt(\%main, $name, $no_expand);
1439
# -------- The ACL configuration --------
1442
print STDOUT "#!!#######################################################!!#\n";
1443
print STDOUT "#!!# This new section of the configuration contains ACLs #!!#\n";
1444
print STDOUT "#!!# (Access Control Lists) derived from the Exim 3 #!!#\n";
1445
print STDOUT "#!!# policy control options. #!!#\n";
1446
print STDOUT "#!!#######################################################!!#\n";
1449
print STDOUT "#!!# These ACLs are crudely constructed from Exim 3 options.\n";
1450
print STDOUT "#!!# They are almost certainly not optimal. You should study\n";
1451
print STDOUT "#!!# them and rewrite as necessary.\n";
1453
print STDOUT "\nbegin acl\n\n";
1456
# Output an ACL for use after the RCPT command. This combines all the previous
1457
# policy checking options.
1459
print STDOUT "#!!# ACL that is used after the RCPT command\n";
1460
print STDOUT "check_recipient:\n";
1462
print STDOUT " # Exim 3 had no checking on -bs messages, so for compatibility\n";
1463
print STDOUT " # we accept if the source is local SMTP (i.e. not over TCP/IP).\n";
1464
print STDOUT " # We do this by testing for an empty sending host field.\n";
1465
print STDOUT " accept hosts = :\n";
1467
if (defined $main{"tls_verify_ciphers"})
1469
print STDOUT " deny ";
1470
print STDOUT "hosts = $main{'tls_verify_hosts'}\n "
1471
if defined $main{"tls_verify_hosts"};
1472
print STDOUT " encrypted = *\n ";
1473
print STDOUT "!encrypted = $main{'tls_verify_ciphers'}\n";
1476
print STDOUT " deny hosts = +auth_hosts\n" .
1477
" message = authentication required\n" .
1478
" !authenticated = *\n"
1479
if defined $main{"auth_hosts"};
1481
print STDOUT " deny hosts = +tls_hosts\n" .
1482
" message = encryption required\n" .
1484
if defined $main{"tls_hosts"};
1486
printf STDOUT (" accept recipients = %s\n",
1487
&acl_quote(&sort_address_list($main{"recipients_reject_except"},
1488
"recipients_reject_except")))
1489
if defined $main{"recipients_reject_except"};
1491
printf STDOUT (" accept senders = %s\n",
1492
&acl_quote(&sort_address_list($main{"recipients_reject_except_senders"},
1493
"recipients_reject_except_senders")))
1494
if defined $main{"recipients_reject_except_senders"};
1496
printf STDOUT (" deny hosts = %s\n", &acl_quote($main{"host_reject"}))
1497
if defined $main{"host_reject"};
1499
printf STDOUT (" deny hosts = %s\n",
1500
&acl_quote($main{"host_reject_recipients"}))
1501
if defined $main{"host_reject_recipients"};
1503
if (defined $main{"rbl_domains"})
1505
my($msg) = "message = host is listed in \$dnslist_domain\n ";
1506
my($hlist) = (defined $main{"rbl_hosts"})?
1507
"hosts = +rbl_hosts\n " : "";
1509
print STDOUT " accept ${hlist}dnslists = $rbl_accept_domains\n"
1510
if defined $rbl_accept_domains;
1511
print STDOUT " deny ${hlist}${msg}dnslists = $rbl_reject_domains\n"
1512
if defined $rbl_reject_domains;
1513
print STDOUT " warn ${hlist}" .
1514
"message = X-Warning: \$sender_host_address is listed at \$dnslist_domain\n" .
1515
" dnslists = $rbl_warn_domains\n"
1516
if defined $rbl_warn_domains;
1518
if (defined $main{"host_accept_relay"})
1520
$hlist .= "hosts = !+relay_hosts\n ";
1521
print STDOUT " accept ${hlist}dnslists = $rbl_accept_skiprelay\n"
1522
if defined $rbl_accept_skiprelay;
1523
print STDOUT " deny ${hlist}${msg}dnslists = $rbl_reject_skiprelay\n"
1524
if defined $rbl_reject_skiprelay;
1525
print STDOUT " warn ${hlist}" .
1526
"message = X-Warning: \$sender_host_address is listed at \$dnslist_domain\n" .
1527
" dnslists = $rbl_warn_skiprelay\n"
1528
if defined $rbl_warn_skiprelay;
1532
printf STDOUT (" deny senders = %s\n",
1533
&acl_quote(&sort_address_list($main{"sender_reject"}, "sender_reject")))
1534
if defined $main{"sender_reject"};
1536
printf STDOUT (" deny senders = %s\n",
1537
&acl_quote(&sort_address_list($main{"sender_reject_recipients"},
1538
"sender_reject_recipients")))
1539
if defined $main{"sender_reject_recipients"};
1541
if (&bool("sender_verify"))
1543
if (defined $main{"sender_verify_hosts_callback"} &&
1544
defined $main{"sender_verify_callback_domains"})
1546
printf STDOUT (" deny hosts = %s\n",
1547
&acl_quote($main{"sender_verify_hosts_callback"}));
1548
printf STDOUT (" sender_domains = %s\n",
1549
&acl_quote($main{"sender_verify_callback_domains"}));
1550
print STDOUT " !verify = sender/callout";
1551
print STDOUT "=$main{\"sender_verify_callback_timeout\"}"
1552
if defined $main{"sender_verify_callback_timeout"};
1556
if (defined $main{"sender_verify_hosts"})
1558
printf STDOUT (" deny hosts = %s\n",
1559
&acl_quote($main{"sender_verify_hosts"}));
1560
print STDOUT " !verify = sender\n";
1564
print STDOUT " require verify = sender\n";
1568
if (&bool("receiver_verify"))
1570
print STDOUT " deny message = unrouteable address\n";
1571
printf STDOUT (" recipients = %s\n",
1572
&acl_quote(&sort_address_list($main{"receiver_verify_addresses"},
1573
"receiver_verify_addresses")))
1574
if defined $main{"receiver_verify_addresses"};
1575
printf STDOUT (" hosts = %s\n",
1576
&acl_quote($main{"receiver_verify_hosts"}))
1577
if defined $main{"receiver_verify_hosts"};
1578
printf STDOUT (" senders = %s\n",
1579
&acl_quote(&sort_address_list($main{"receiver_verify_senders"},
1580
"receiver_verify_senders")))
1581
if defined $main{"receiver_verify_senders"};
1582
print STDOUT " !verify = recipient\n";
1585
print STDOUT " accept domains = +local_domains\n"
1586
if $local_domains !~ /^\s*$/;
1588
print STDOUT " accept domains = +relay_domains\n"
1589
if $relay_domains !~ /^\s*$/;
1591
if (defined $main{"host_accept_relay"})
1593
if (defined $main{"sender_address_relay"})
1595
if (defined $main{"sender_address_relay_hosts"})
1597
printf STDOUT (" accept hosts = %s\n",
1598
&acl_quote($main{"sender_address_relay_hosts"}));
1599
print STDOUT " endpass\n";
1600
print STDOUT " message = invalid sender\n";
1601
printf STDOUT (" senders = %s\n",
1602
&acl_quote(&sort_address_list($main{"sender_address_relay"},
1603
"sender_address_relay")));
1604
print STDOUT " accept hosts = +relay_hosts\n";
1608
print STDOUT " accept hosts = +relay_hosts\n";
1609
print STDOUT " endpass\n";
1610
print STDOUT " message = invalid sender\n";
1611
printf STDOUT (" senders = %s\n",
1612
&acl_quote(&sort_address_list($main{"sender_address_relay"},
1613
"sender_address_relay")));
1618
print STDOUT " accept hosts = +relay_hosts\n";
1622
print STDOUT " accept hosts = +auth_relay_hosts\n" .
1624
" message = authentication required\n" .
1625
" authenticated = *\n"
1626
if defined $main{"host_auth_accept_relay"};
1628
print STDOUT " accept hosts = +tls_relay_hosts\n" .
1630
" message = encryption required\n" .
1632
if defined $main{"tls_host_accept_relay"};
1634
print STDOUT " deny message = relay not permitted\n\n";
1637
# Output an ACL for use after the DATA command. This is concerned with
1640
print STDOUT "#!!# ACL that is used after the DATA command\n";
1641
print STDOUT "check_message:\n";
1643
# Default for headers_checks_fail is true
1645
if (!defined $main{"headers_checks_fail"} ||
1646
$main{"headers_checks_fail"} eq "true")
1648
print STDOUT " require verify = header_syntax\n"
1649
if &bool("headers_check_syntax");
1650
print STDOUT " require verify = header_sender\n"
1651
if &bool("headers_sender_verify");
1652
print STDOUT " accept senders = !:\n require verify = header_sender\n"
1653
if &bool("headers_sender_verify_errmsg");
1657
print STDOUT " warn !verify = header_syntax\n"
1658
if &bool("headers_check_syntax");
1659
print STDOUT " warn !verify = header_sender\n"
1660
if &bool("headers_sender_verify");
1661
print STDOUT " accept senders = !:\n warn !verify = header_sender\n"
1662
if &bool("headers_sender_verify_errmsg");
1665
print STDOUT " accept\n\n";
1668
# Output an ACL for AUTH if required
1670
if (defined $main{"auth_over_tls_hosts"})
1672
print STDOUT "#!!# ACL that is used after the AUTH command\n" .
1674
" accept hosts = +auth_over_tls_hosts\n" .
1676
" message = STARTTLS required before AUTH\n" .
1677
" encrypted = *\n" .
1682
# Output ACLs for ETRN, EXPN, and VRFY if required
1684
if (defined $main{"smtp_etrn_hosts"})
1686
print STDOUT "#!!# ACL that is used after the ETRN command\n" .
1688
print STDOUT " deny hosts = +auth_hosts\n" .
1689
" message = authentication required\n" .
1690
" !authenticated = *\n"
1691
if defined $main{"auth_hosts"};
1692
print STDOUT " accept hosts = $main{\"smtp_etrn_hosts\"}\n\n";
1695
if (defined $main{"smtp_expn_hosts"})
1697
print STDOUT "#!!# ACL that is used after the EXPN command\n" .
1699
print STDOUT " deny hosts = +auth_hosts\n" .
1700
" message = authentication required\n" .
1701
" !authenticated = *\n"
1702
if defined $main{"auth_hosts"};
1703
print STDOUT " accept hosts = $main{\"smtp_expn_hosts\"}\n\n";
1706
if (&bool("smtp_verify"))
1708
print STDOUT "#!!# ACL that is used after the VRFY command\n" .
1710
print STDOUT " deny hosts = +auth_hosts\n" .
1711
" message = authentication required\n" .
1712
" !authenticated = *\n"
1713
if defined $main{"auth_hosts"};
1714
print STDOUT " accept\n\n";
1717
# -------- The authenticators --------
1720
for ($i = $auth_start; $i < $clen; $i++)
1724
if ($c[$i] !~ /^\s*(#|$)/)
1726
print STDOUT "\nbegin authenticators\n\n";
1730
print STDOUT "$c[$i]\n";
1734
# -------- Rewrite section --------
1737
for ($i = $rewrite_start; $i < $clen && $i < $auth_start - 1; $i++)
1741
if ($c[$i] !~ /^\s*(#|$)/)
1743
print STDOUT "\nbegin rewrite\n\n";
1747
&print_no_expand($c[$i]);
1751
# -------- The routers configuration --------
1753
# The new routers configuration is created out of the old directors and routers
1754
# configuration. We put the old routers first, adding a "domains" option to
1755
# any that don't have one, to make them select the domains that do not match
1756
# the original local_domains. The routers get modified as necessary, and the
1757
# final one has "no_more" set, unless it has conditions. In that case we have
1758
# to add an extra router to be sure of failing all non-local addresses that
1759
# fall through. We do this also if there are no routers at all. The old
1760
# directors follow, modified as required.
1766
print STDOUT "#!!#######################################################!!#\n";
1767
print STDOUT "#!!# Here follow routers created from the old routers, #!!#\n";
1768
print STDOUT "#!!# for handling non-local domains. #!!#\n";
1769
print STDOUT "#!!#######################################################!!#\n";
1771
print STDOUT "\nbegin routers\n\n";
1773
for ($i = $router_start; $i < $clen; $i++)
1775
$type = &checkline($c[$i]);
1776
last if $type eq "end";
1778
if ($type eq "comment") { push(@comments, "$c[$i]\n"); next; }
1780
# When we hit the start of a driver, modify its options as necessary,
1781
# and then output it from the stored option settings, having first output
1782
# and previous comments.
1784
if ($type eq "driver")
1786
print STDOUT shift @comments while scalar(@comments) > 0;
1788
$hash = $driverlist{"$prefix$name"};
1789
$driver = $$hash{"driver"};
1790
print STDOUT "$name:\n";
1793
! defined $$hash{"domains"} &&
1794
! defined $$hash{"local_parts"} &&
1795
! defined $$hash{"senders"} &&
1796
! defined $$hash{"condition"} &&
1797
! defined $$hash{"require_files"} &&
1798
(!defined $$hash{"verify_only"} || $$hash{"verify_only"} eq "false") &&
1799
(!defined $$hash{"verify"} || $$hash{"verify"} eq "true");
1801
# Create a "domains" setting if there isn't one, unless local domains
1802
# was explicitly empty.
1804
$$hash{"domains"} = "! +local_domains"
1805
if !defined $$hash{"domains"} && $local_domains !~ /^\s*$/;
1807
# If the router had a local_parts setting, add caseful_local_part
1809
$$hash{"caseful_local_part"} = "true" if defined $$hash{"local_parts"};
1811
# If the router has "self=local" set, change it to "self=pass", and
1812
# set pass_router to the router that was the first director. Change the
1813
# obsolete self settings of "fail_hard" and "fail_soft" to "fail" and
1816
if (defined $$hash{"self"})
1818
if ($$hash{"self"} eq "local")
1820
$$hash{"self"} = "pass";
1821
$$hash{"pass_router"} = $first_director;
1823
elsif ($$hash{"self"} eq "fail_hard")
1825
$$hash{"self"} = "fail";
1827
elsif ($$hash{"self"} eq "fail_soft")
1829
$$hash{"self"} = "pass";
1833
# If the router had a require_files setting, check it for user names
1834
# and colons that are part of expansion items
1836
if (defined $$hash{"require_files"})
1838
&check_require($$hash{"require_files"}, "'$name' router");
1839
if (($$hash{"require_files"} =~ s/(\$\{\w+):/$1::/g) > 0 ||
1840
($$hash{"require_files"} =~ s/ldap:/ldap::/g) > 0)
1844
"*** A setting of require_files in the $name router contains\n" .
1845
" a colon in what appears to be an expansion item. In Exim 3, the\n" .
1846
" whole string was expanded before splitting the list, but in Exim 4\n" .
1847
" each item is expanded separately, so colons that are not list\n" .
1848
" item separators have to be doubled. One or more such colons in this\n" .
1849
" list have been doubled as a precaution. Please check the result.\n";
1853
# If the router had a "senders" setting, munge the address list
1855
$$hash{"senders"} = &sort_address_list($$hash{"senders"}, "senders")
1856
if defined $$hash{"senders"};
1858
# ---- Changes to domainlist router ----
1860
if ($driver eq "domainlist")
1862
&abolished($hash, "A domainlist router",
1863
"modemask", "owners", "owngroups",
1864
"qualify_single", "search_parents");
1866
# The name has changed
1868
$$hash{"driver"} = "manualroute";
1870
# Turn "route_file", "route_query" and "route_queries" into lookups for
1873
if (defined $$hash{"route_file"})
1875
$$hash{"route_data"} = "\${lookup\{\$domain\}$$hash{'search_type'}" .
1876
"\{$$hash{'route_file'}\}\}";
1878
elsif (defined $$hash{"route_query"})
1880
$$hash{"route_data"} = "\${lookup $$hash{'search_type'}" .
1881
"\{" . &unquote($$hash{'route_query'}) . "\}\}";
1883
elsif (defined $$hash{"route_queries"})
1886
$$hash{"route_data"} = "";
1887
$route_queries = $$hash{'route_queries'};
1888
$route_queries =~ s/^"(.*)"$/$1/s;
1889
$route_queries =~ s/::/++colons++/g;
1890
@qq = split(/:/, $route_queries);
1894
$q =~ s/\+\+colons\+\+/:/g;
1899
$$hash{"route_data"} .= "\\\n {";
1902
$$hash{"route_data"} .= "\${lookup $$hash{'search_type'} \{$q\}\{\$value\}";
1906
$$hash{"route_data"} .= "}" x $endkets;
1909
delete $$hash{"route_file"};
1910
delete $$hash{"route_query"};
1911
delete $$hash{"route_queries"};
1912
delete $$hash{"search_type"};
1914
# But we can't allow both route_data and route_list
1916
if (defined $$hash{"route_data"} && defined $$hash{"route_list"})
1920
"** An Exim 3 'domainlist' router called '$name' contained a 'route_list'\n" .
1921
" option as well as a setting of 'route_file', 'route_query', or\n" .
1922
" 'route_queries'. The latter has been turned into a 'route_data' setting,\n".
1923
" but in Exim 4 you can't have both 'route_data' and 'route_list'. You'll\n" .
1924
" have to rewrite this router; in the meantime, 'route_list' has been\n" .
1926
print STDOUT "#!!# route_list option removed\n";
1927
delete $$hash{"route_list"};
1930
# Change bydns_a into bydns in a route_list; also bydns_mx, but that
1931
# works differently.
1933
if (defined $$hash{"route_list"})
1935
$$hash{"route_list"} =~ s/bydns_a/bydns/g;
1936
if ($$hash{"route_list"} =~ /bydns_mx/)
1938
$$hash{"route_list"} =~ s/bydns_mx/bydns/g;
1941
"*** An Exim 3 'domainlist' router called '$name' contained a 'route_list'\n" .
1942
" option which used 'bydns_mx'. This feature no longer exists in Exim 4.\n" .
1943
" It has been changed to 'bydns', but it won't have the same effect,\n" .
1944
" because it will look for A rather than MX records. Use the 'dnslookup'\n" .
1945
" router to do MX lookups - if you want to override the hosts found from\n" .
1946
" MX records, you should route to a special 'smtp' transport which has\n" .
1947
" both 'hosts' and 'hosts_override' set.\n";
1951
# Arrange to not expand regex
1953
$$hash{"route_list"} = &no_expand_regex($$hash{"route_list"}, ";")
1954
if (defined $$hash{"route_list"})
1958
# ---- Changes to iplookup router ----
1960
elsif ($driver eq "iplookup")
1962
&renamed($hash, "service", "port");
1966
# ---- Changes to lookuphost router ----
1968
elsif ($driver eq "lookuphost")
1970
$$hash{"driver"} = "dnslookup";
1972
if (defined $$hash{"gethostbyname"})
1976
"** An Exim 3 'lookuphost' router called '$name' used the 'gethostbyname'\n" .
1977
" option, which no longer exists. You will have to rewrite it.\n";
1978
print STDOUT "#!!# gethostbyname option removed\n";
1979
delete $$hash{"gethostbyname"};
1982
$$hash{"mx_domains"} = &no_expand_regex($$hash{"mx_domains"})
1983
if defined $$hash{"mx_domains"};
1987
# ---- Changes to the queryprogram router ----
1989
elsif ($driver eq "queryprogram")
1993
"** The configuration contains a 'queryprogram' router. Please note that\n" .
1994
" the specification for the text that is returned by the program run\n" .
1995
" by this router has changed in Exim 4. You will need to modify your\n" .
1998
if (!defined $$hash{'command_user'})
2002
"** The 'queryprogram' router called '$name' does not have a setting for\n" .
2003
" the 'command_user' option. This is mandatory in Exim 4. A setting of\n" .
2004
" 'nobody' has been created.\n";
2005
$$hash{"command_user"} = "nobody";
2010
# -------------------------------------
2012
# Output the router's option settings
2018
# Skip past any continuation lines for an option setting
2019
while ($c[$i] =~ /\\\s*$/s && $i < $clen - 1)
2022
$i++ while ($c[$i] =~ /^\s*#/);
2026
# Add "no_more" to the final driver from the old routers, provided it had no
2027
# conditions. Otherwise, or if there were no routers, make up one to fail all
2028
# non-local domains.
2032
print STDOUT " no_more\n";
2033
print STDOUT shift @comments while scalar(@comments) > 0;
2037
print STDOUT shift @comments while scalar(@comments) > 0;
2038
print STDOUT "\n#!!# This new router is put here to fail all domains that\n";
2039
print STDOUT "#!!# were not in local_domains in the Exim 3 configuration.\n\n";
2040
print STDOUT "fail_remote_domains:\n";
2041
print STDOUT " driver = redirect\n";
2042
print STDOUT " domains = ! +local_domains\n";
2043
print STDOUT " allow_fail\n";
2044
print STDOUT " data = :fail: unrouteable mail domain \"\$domain\"\n\n";
2047
# Now copy the directors, making appropriate changes
2050
print STDOUT "#!!#######################################################!!#\n";
2051
print STDOUT "#!!# Here follow routers created from the old directors, #!!#\n";
2052
print STDOUT "#!!# for handling local domains. #!!#\n";
2053
print STDOUT "#!!#######################################################!!#\n";
2056
for ($i = $director_start; $i < $clen; $i++)
2058
$type = &checkline($c[$i]);
2059
last if $type eq "end";
2061
if ($type eq "comment") { print STDOUT "$c[$i]\n"; next; }
2063
undef $second_router;
2065
if ($type eq "driver")
2067
$hash = $driverlist{"$prefix$name"};
2068
$driver = $$hash{"driver"};
2069
print STDOUT "$name:\n";
2071
$$hash{"caseful_local_part"} = "true" if $add_caseful_local_part;
2073
if (defined $$hash{"local_parts"} &&
2074
(defined $$hash{"prefix"} || defined $hash{"suffix"}))
2078
"** The Exim 3 configuration contains a director called '$name' which has\n" .
2079
" 'local_parts' set, together with either or both of 'prefix' and 'suffix'\n".
2080
" This combination has a different effect in Exim 4, where the affix\n" .
2081
" is removed *before* 'local_parts' is tested. You will probably need\n" .
2082
" to make changes to this driver.\n";
2085
&renamed($hash, "prefix", "local_part_prefix");
2086
&renamed($hash, "prefix_optional", "local_part_prefix_optional");
2087
&renamed($hash, "suffix", "local_part_suffix");
2088
&renamed($hash, "suffix_optional", "local_part_suffix_optional");
2089
&renamed($hash, "new_director", "redirect_router");
2091
&handle_current_and_home_directory($hash, $driver, $name);
2093
# If the director had a require_files setting, check it for user names
2094
# and colons that are part of expansion items
2096
if (defined $$hash{"require_files"})
2098
&check_require($$hash{"require_files"}, "'$name' director");
2099
if (($$hash{"require_files"} =~ s/(\$\{\w+):/$1::/g) > 0 ||
2100
($$hash{"require_files"} =~ s/ldap:/ldap::/g) > 0)
2104
"*** A setting of require_files in the $name director contains\n" .
2105
" a colon in what appears to be an expansion item. In Exim 3, the\n" .
2106
" whole string was expanded before splitting the list, but in Exim 4\n" .
2107
" each item is expanded separately, so colons that are not list\n" .
2108
" item separators have to be doubled. One or more such colons in this\n" .
2109
" list have been doubled as a precaution. Please check the result.\n";
2113
# If the director had a "senders" setting, munge the address list
2115
$$hash{"senders"} = &sort_address_list($$hash{"senders"}, "senders")
2116
if defined $$hash{"senders"};
2118
# ---- Changes to aliasfile director ----
2120
if ($driver eq "aliasfile")
2122
&abolished($hash, "An aliasfile director",
2123
"directory2_transport", "freeze_missing_include",
2124
"modemask", "owners", "owngroups");
2126
$$hash{"driver"} = "redirect";
2128
$key = "\$local_part";
2129
$key = "\$local_part\@\$domain"
2130
if defined $$hash{"include_domain"} &&
2131
$$hash{"include_domain"} eq "true";
2132
delete $$hash{"include_domain"};
2134
if (defined $$hash{"forbid_special"} && $$hash{"forbid_special"} eq "true")
2136
$$hash{"forbid_blackhole"} = "true";
2140
$$hash{"allow_defer"} = "true";
2141
$$hash{"allow_fail"} = "true";
2143
delete $$hash{"forbid_special"};
2145
# Deal with "file", "query", or "queries"
2147
if (defined $$hash{"file"})
2150
"\$\{lookup\{$key\}$$hash{'search_type'}\{$$hash{'file'}\}\}";
2151
if (defined $$hash{"optional"} && $$hash{"optional"} eq "true")
2154
"\$\{if exists\{$$hash{'file'}\}\{$$hash{'data'}\}\}";
2156
delete $$hash{"optional"};
2158
elsif (defined $$hash{"query"})
2160
&abolished($hash, "An aliasfile director", "optional");
2161
$$hash{"data"} = "\${lookup $$hash{'search_type'} " .
2162
"\{" . &unquote($$hash{'query'}) . "\}\}";
2164
else # Must be queries
2166
&abolished($hash, "An aliasfile director", "optional");
2168
$$hash{"data"} = "";
2169
$queries = $$hash{'queries'};
2170
$queries =~ s/^"(.*)"$/$1/s;
2171
$queries =~ s/::/++colons++/g;
2172
@qq = split(/:/, $queries);
2176
$q =~ s/\+\+colons\+\+/:/g;
2181
$$hash{"data"} .= "\\\n {";
2184
$$hash{"data"} .= "\${lookup $$hash{'search_type'} \{$q\}\{\$value\}";
2188
$$hash{"data"} .= "}" x $endkets;
2191
$$hash{"data"} = "\${expand:$$hash{'data'}\}"
2192
if (defined $$hash{"expand"} && $$hash{"expand"} eq "true");
2194
delete $$hash{"expand"};
2195
delete $$hash{"file"};
2196
delete $$hash{"query"};
2197
delete $$hash{"queries"};
2198
delete $$hash{"search_type"};
2200
# Turn aliasfile + transport into accept + condition
2202
if (defined $$hash{'transport'})
2205
if (!defined $$hash{'condition'})
2208
"** The Exim 3 configuration contains an aliasfile director called '$name',\n".
2209
" which has 'transport' set. This has been turned into an 'accept' router\n".
2210
" with a 'condition' setting, but should be carefully checked.\n";
2211
$$hash{'driver'} = "accept";
2212
$$hash{'condition'} =
2213
"\$\{if eq \{\}\{$$hash{'data'}\}\{no\}\{yes\}\}";
2214
delete $$hash{'data'};
2215
delete $$hash{'allow_defer'};
2216
delete $$hash{'allow_fail'};
2221
"** The Exim 3 configuration contains an aliasfile director called '$name',\n".
2222
" which has 'transport' set. This cannot be turned into an 'accept' router\n".
2223
" with a 'condition' setting, because there is already a 'condition'\n" .
2224
" setting. It has been left as 'redirect' with a transport, which is\n" .
2225
" invalid - you must sort this one out.\n";
2231
# ---- Changes to forwardfile director ----
2233
elsif ($driver eq "forwardfile")
2235
&abolished($hash, "A forwardfile director",
2236
"check_group", "directory2_transport",
2237
"freeze_missing_include", "match_directory",
2240
&renamed($hash, "filter", "allow_filter");
2242
$$hash{"driver"} = "redirect";
2243
$$hash{"check_local_user"} = "true"
2244
if !defined $$hash{"check_local_user"};
2246
if (defined $$hash{"forbid_pipe"} && $$hash{"forbid_pipe"} eq "true")
2248
print STDOUT "#!!# forbid_filter_run added because forbid_pipe is set\n";
2249
$$hash{"forbid_filter_run"} = "true";
2252
if (defined $$hash{'allow_system_actions'} &&
2253
$$hash{'allow_system_actions'} eq 'true')
2255
$$hash{'allow_freeze'} = "true";
2257
delete $$hash{'allow_system_actions'};
2259
# If file_directory is defined, use it to qualify relative paths; if not,
2260
# and check_local_user is defined, use $home. Remove file_directory from
2264
if (defined $$hash{"file_directory"})
2266
$dir = $$hash{"file_directory"} . "/";
2267
delete $$hash{"file_directory"};
2269
elsif ($$hash{"check_local_user"} eq "true")
2274
# If it begins with an upper case letter, guess that this is really
2277
if (defined $$hash{"file"} && $$hash{"file"} !~ /^[\/A-Z]/)
2279
$$hash{"file"} = $dir . $$hash{"file"};
2284
# ---- Changes to localuser director ----
2286
elsif ($driver eq "localuser")
2288
&abolished($hash, "A localuser director", "match_directory");
2289
$$hash{"driver"} = "accept";
2290
$$hash{"check_local_user"} = "true";
2294
# ---- Changes to smartuser director ----
2296
elsif ($driver eq "smartuser")
2298
&abolished($hash, "A smartuser director", "panic_expansion_fail");
2300
$transport = $$hash{"transport"};
2301
$new_address = $$hash{"new_address"};
2303
if (defined $transport && defined $new_address)
2307
"** The Exim 3 configuration contains a smartuser director called '$name',\n".
2308
" which has both 'transport' and 'new_address' set. This has been turned\n".
2309
" into two routers for Exim 4. However, if the new address contains a\n" .
2310
" reference to \$local_part, this won't work correctly. In any case, you\n".
2311
" may be able to make it tidier by rewriting.\n";
2312
$$hash{"driver"} = "redirect";
2313
$$hash{"data"} = $new_address;
2314
$$hash{"redirect_router"} = "${name}_part2";
2316
$second_router = "\n".
2317
"#!!# This router is invented to go with the previous one because\n".
2318
"#!!# in Exim 4 you can't have a change of address and a transport\n".
2319
"#!!# setting in the same router as you could in Exim 3.\n\n" .
2321
" driver = accept\n".
2322
" condition = \$\{if eq\{\$local_part@\$domain\}" .
2323
"\{$new_address\}\{yes\}\{no\}\}\n".
2324
" transport = $$hash{'transport'}\n";
2326
delete $$hash{"new_address"};
2327
delete $$hash{"transport"};
2329
elsif (defined $new_address)
2331
$$hash{"driver"} = "redirect";
2332
$$hash{"data"} = $new_address;
2333
$$hash{"allow_defer"} = "true";
2334
$$hash{"allow_fail"} = "true";
2335
delete $$hash{"new_address"};
2337
else # Includes the case of neither set (verify_only)
2339
$$hash{"driver"} = "accept";
2340
if (defined $$hash{"rewrite"})
2344
"** The Exim 3 configuration contains a setting of the 'rewrite' option on\n".
2345
" a smartuser director called '$name', but this director does not have\n".
2346
" a setting of 'new_address', so 'rewrite' has no effect. The director\n".
2347
" has been turned into an 'accept' router, and 'rewrite' has been discarded.";
2348
delete $$hash{"rewrite"};
2354
# -------------------------------------
2356
# For ex-directors that don't have check_local_user set, add
2357
# retry_use_local_part to imitate what Exim 3 would have done.
2359
$$hash{"retry_use_local_part"} = "true"
2360
if (!defined $$hash{"check_local_user"} ||
2361
$$hash{"check_local_user"} eq "false") ;
2363
# Output the router's option settings
2367
# Output an auxiliary router if one is needed
2369
print STDOUT $second_router if defined $second_router;
2374
# Skip past any continuation lines for an option setting
2375
while ($c[$i] =~ /\\\s*$/s)
2378
$i++ while ($c[$i] =~ /^\s*#/);
2384
# -------- The transports configuration --------
2388
for ($i = $transport_start; $i < $clen; $i++)
2390
$type = &checkline($c[$i]);
2391
last if $type eq "end";
2393
if ($type eq "comment") { print STDOUT "$c[$i]\n"; next; }
2397
print STDOUT "begin transports\n\n";
2401
if ($type eq "driver")
2403
$hash = $driverlist{"$prefix$name"};
2404
$driver = $$hash{"driver"};
2405
print STDOUT "$name:\n";
2407
# ---- Changes to the appendfile transport ----
2409
if ($driver eq "appendfile")
2411
&renamed($hash, "prefix", "message_prefix");
2412
&renamed($hash, "suffix", "message_suffix");
2413
&abolished($hash, "An appendfile transport",
2414
"require_lockfile");
2415
&handle_batch_and_bsmtp($hash);
2416
if (defined $$hash{"from_hack"} && $$hash{"from_hack"} eq "false")
2418
print STDOUT "#!!# no_from_hack replaced by check_string\n";
2419
$$hash{"check_string"} = "";
2421
delete $$hash{"from_hack"};
2424
# ---- Changes to the lmtp transport ----
2426
elsif ($driver eq "lmtp")
2428
if (defined $$hash{"batch"} && $$hash{"batch"} ne "none")
2430
$$hash{"batch_max"} = "100" if !defined $$hash{"batch_max"};
2431
$$hash{"batch_id"} = "\$domain" if $$hash{"batch"} eq "domain";
2435
$$hash{"batch_max"} = "1" if defined $$hash{"batch_max"};
2437
delete $$hash{"batch"};
2440
# ---- Changes to the pipe transport ----
2442
elsif ($driver eq "pipe")
2444
&renamed($hash, "prefix", "message_prefix");
2445
&renamed($hash, "suffix", "message_suffix");
2446
&handle_batch_and_bsmtp($hash);
2447
if (defined $$hash{"from_hack"} && $$hash{"from_hack"} eq "false")
2449
print STDOUT "#!!# no_from_hack replaced by check_string\n";
2450
$$hash{"check_string"} = "";
2452
delete $$hash{"from_hack"};
2455
# ---- Changes to the smtp transport ----
2457
elsif ($driver eq "smtp")
2459
&abolished($hash, "An smtp transport", "mx_domains");
2460
&renamed($hash, "service", "port");
2461
&renamed($hash, "tls_verify_ciphers", "tls_require_ciphers");
2462
&renamed($hash, "authenticate_hosts", "hosts_try_auth");
2464
if (defined $$hash{"batch_max"})
2466
print STDOUT "#!!# batch_max renamed connection_max_messages\n";
2467
$$hash{"connection_max_messages"} = $$hash{"batch_max"};
2468
delete $$hash{"batch_max"};
2471
foreach $o ("hosts_try_auth", "hosts_avoid_tls", "hosts_require_tls",
2472
"mx_domains", "serialize_hosts")
2474
$$hash{$o} = &no_expand_regex($$hash{$o}) if defined $$hash{$o};
2478
&outdriver($driverlist{"$prefix$name"});
2482
# Skip past any continuation lines for an option setting
2483
while ($c[$i] =~ /\\\s*$/s)
2486
$i++ while ($c[$i] =~ /^\s*#/);
2491
# -------- The retry configuration --------
2494
for ($i = $retry_start; $i < $clen && $i < $rewrite_start - 1; $i++)
2498
if ($c[$i] !~ /^\s*(#|$)/)
2500
print STDOUT "\nbegin retry\n\n";
2504
&print_no_expand($c[$i]);
2507
print STDOUT "\n# End of Exim 4 configuration\n";
2509
print STDERR "\n*******************************************************\n";
2510
print STDERR "***** Please review the generated file carefully. *****\n";
2511
print STDERR "*******************************************************\n\n";