#!/usr/bin/perl -w # -*-CPerl-*- # Script to configure Postfix. # Based on code by Colin Walters , # and John Goerzen . use strict; use warnings; use Debconf::Client::ConfModule qw(:all); use Fcntl; my $version = version(2.0); capb("backup"); title("Postfix Configuration"); # begin configuration script my $topstate; my $back; my $noninteractive; my $skiprelayhost; # Regexps for checking domain names, blatantly stolen from exim config my $rfc1035_label_re= '[0-9A-Za-z]([-0-9A-Za-z]*[0-9A-Za-z])?'; my $rfc1035_domain_re= "$rfc1035_label_re(\\.$rfc1035_label_re)*"; my $network_re= '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}/[0-9]{1,2}'; $topstate = "start"; my $distribution = lc(`lsb_release -is 2>/dev/null`); $distribution = 'debian' if $distribution eq ''; while ($topstate ne "done") { TOPSTATE: { if ($topstate eq "start") { if (fget("postfix/main_mailer_type", "isdefault") eq "true") { if (-f "/etc/postfix/main.cf") { set("postfix/main_mailer_type", "No configuration"); } } my $pri = "high"; $pri = "medium" if ($ARGV[1] ne "" && $distribution eq "ubuntu"); $noninteractive = (((input($pri, "postfix/main_mailer_type"))[0]) == 30); if ($noninteractive) { my $mailertype = get("postfix/main_mailer_type"); if ($mailertype eq "No configuration") { # We can't display a note here, because it could send mail, # which isn't configured... #$noninteractive = ((input("critical", "postfix/not_configured"))[0] == 30); #go(); fset("postfix/newaliases", "run", "false"); $topstate="ending-setup"; } else { $topstate="mailname"; } } else { go(); $back = (((go())[0]) == 30); my $mailertype = get("postfix/main_mailer_type"); if ($mailertype eq "No configuration") { $topstate="ending-setup"; } else { fset("postfix/main_mailer_type", "changed", "true"); fset("postfix/newaliases", "run", "true"); if ($back) { fset("postfix/main_mailer_type", "isdefault", "true"); } else { fset("postfix/main_mailer_type", "changed", "true"); $topstate = "mailname"; if (!(($mailertype eq "Internet with smarthost") || ($mailertype eq "Satellite system") || ($mailertype eq "HP"))) { set("postfix/relayhost", ""); fset("postfix/relayhost", "changed", "true"); } } } } } if ($topstate eq "mailname") { my $mailname; if (-f "/etc/mailname") { if (open my $fh, '<', "/etc/mailname") { $mailname = <$fh>; close $fh; chomp $mailname; } } if (!defined($mailname) || $mailname eq "") { $mailname = `hostname --fqdn 2>/dev/null` || "localdomain"; chomp $mailname; } # broken mailname, change it to the default, and prompt. if (lc($mailname) eq "ubuntu.com" || lc($mailname) eq "debian.org") { fset("postfix/mailname", "isdefault", "true"); $mailname = `hostname --fqdn 2>/dev/null` || "localdomain"; chomp $mailname; } if (fget("postfix/mailname", "isdefault") eq "true") { set("postfix/mailname", $mailname); } $noninteractive = (((input("high", "postfix/mailname"))[0]) == 30); if ($noninteractive) { $topstate = "relayhost"; } else { $back = (((go())[0]) == 30); if ($back) { fset("postfix/main_mailer_type", "isdefault", "true"); fset("postfix/mailname", "isdefault", "true"); $topstate = "start"; } else { # error checking my $mailname = lc(get("postfix/mailname")); fset("postfix/mailname", "changed", "true"); if ($mailname eq "ubuntu.com" || $mailname eq "debian.org") { fset("postfix/mailname", "isdefault", "true"); } elsif ($mailname =~ /$rfc1035_domain_re/ || $mailname eq "==default==") { # their mailname passed error checking, go on $topstate = "relayhost"; } else { set("postfix/rfc1035_violation", "false"); fset("postfix/rfc1035_violation", "isdefault", "true"); subst("postfix/rfc1035_violation", "enteredstring", $mailname); $noninteractive = (((input("high", "postfix/rfc1035_violation"))[0]) == 30); $back = (((go())[0]) == 30); if ($back) { fset("postfix/mailname", "isdefault", "true"); # and back around to ask mailname again. } if (get("postfix/rfc1035_violation") eq "true") { # they wanted to continue despite the error $topstate = "relayhost"; } else { fset("postfix/mailname", "isdefault", "true"); # and back around to ask mailname again. } } } } } if ($topstate eq "relayhost") { my $mailertype = get("postfix/main_mailer_type"); if (($mailertype eq "Internet with smarthost") || ($mailertype eq "Satellite system")) { if (fget("postfix/relayhost", "isdefault") eq "true") { my $hostname = `hostname --domain 2>/dev/null` || "localdomain"; chomp $hostname; my $relayname = "smtp." . $hostname; set("postfix/relayhost", $relayname); } $noninteractive = (((input("high", "postfix/relayhost"))[0]) == 30); $skiprelayhost=0; } else { # skip relayhost if we're an "Internet site" or a "Local only" $topstate = "root"; $noninteractive=1; $skiprelayhost=1; } if ($noninteractive) { $topstate = "root"; } else { $back = (((go())[0]) == 30); if ($back) { fset("postfix/mailname", "isdefault", "true"); fset("postfix/relayhost", "isdefault", "true"); $topstate = "mailname"; # we skip back to the last question of equal or higher priority } else { my $host = get("postfix/relayhost"); if ($host =~ /[\s,]/) { fset("postfix/relayhost", "isdefault", "true"); } else { fset("postfix/relayhost", "changed", "true"); $topstate = "root"; } } } } if ($topstate eq "root") { if (fget("postfix/root_address", "isdefault") eq "true") { my @l = (); if (open my $fh, '-|', "getent passwd 1000") { @l=<$fh>; close $fh; } if ($#l > 0) { $l[0] =~ s/:.*$//; set("postfix/root_address",$l[0]); fset("postfix/root_address", "changed", "true"); } } $noninteractive = (((input("medium", "postfix/root_address"))[0]) == 30); if ($noninteractive) { $topstate="destinations"; } else { $back = (((go())[0]) == 30); if ($back) { fset("postfix/relayhost", "isdefault", "true"); fset("postfix/root_address", "isdefault", "true"); if ($skiprelayhost) { fset("postfix/mailname", "isdefault", "true"); $topstate = "mailname"; } else { $topstate = "relayhost"; } } else { fset("postfix/root_address", "changed", "true"); $topstate="destinations"; } } } if ($topstate eq "destinations") { my $mailertype = get("postfix/main_mailer_type"); my $hostname = `hostname --fqdn 2>/dev/null` || "localhost"; chomp $hostname; my $domain = `hostname --domain 2>/dev/null` || "localdomain"; chomp $domain; my $mailname = get("postfix/mailname") || "localhost"; my $destinations; my $priority="medium"; if (fget("postfix/destinations", "set") eq "true") { if ((-x "/usr/sbin/postconf") && (-f "/etc/postfix/main.cf")) { if (open my $fh, '-|', "postconf -hx mydestination") { $destinations=<$fh>; close $fh; chomp $destinations; set("postfix/destinations", $destinations); } } } else { if ($mailertype eq "Internet Site") { if ($mailname eq $hostname) { $destinations = join ", ",("\$myhostname", $mailname, "localhost." . $domain, ", localhost"); } else { $destinations = join ", ",("\$myhostname", $mailname, $hostname, "localhost." . $domain . ", localhost"); } } else { # don't accept mail for $mailname by default if we have a relayhost or local only mail, # unless the mailname bears no resemblance to $myorigin. $destinations = join ", ",("\$myhostname", $hostname, "localhost." . $domain . ", localhost" ); unless ( $hostname =~ m/(^|[\.])$mailname$/ ) { $destinations = $mailname . ", " . $destinations; } } set("postfix/destinations", $destinations); fset("postfix/destinations","set","true"); } if ($mailertype eq "Local only") { $priority="low"; } $noninteractive = (((input($priority, "postfix/destinations"))[0]) == 30); if ($noninteractive) { $topstate = "chattr"; } else { $back = (((go())[0]) == 30); if ($back) { fset("postfix/relayhost", "isdefault", "true"); fset("postfix/destinations", "isdefault", "true"); $topstate = "relayhost"; } else { fset("postfix/destinations", "changed", "true"); $topstate = "chattr"; } } } if ($topstate eq "chattr") { $noninteractive = (((input("medium", "postfix/chattr"))[0]) == 30); if ($noninteractive) { $topstate = "mynetworks"; } else { $back = (((go())[0]) == 30); if ($back) { fset("postfix/destinations", "isdefault", "true"); fset("postfix/chattr", "isdefault", "true"); $topstate = "destinations"; } else { fset("postfix/chattr", "changed", "true"); $topstate = "mynetworks"; } } } if ($topstate eq "mynetworks") { if ((-x "/usr/sbin/postconf") && (-f "/etc/postfix/main.cf")) { my $mynetworks; if (open my $fh, '-|', "postconf -hx mynetworks") { $mynetworks=<$fh>; close $fh; chomp $mynetworks; set("postfix/mynetworks", $mynetworks); } } $noninteractive = (((input("low", "postfix/mynetworks"))[0]) == 30); if ($noninteractive) { $topstate = "procmail"; } else { $back = (((go())[0]) == 30); if ($back) { fset("postfix/chattr", "isdefault", "true"); fset("postfix/mynetworks", "isdefault", "true"); $topstate = "chattr"; } else { fset("postfix/mynetworks", "changed", "true"); $topstate = "procmail"; } } } if ($topstate eq "procmail") { if (fget("postfix/procmail", "isdefault") eq "true") { my $pmdefault="false"; if (-x "/usr/bin/procmail") { $pmdefault="true"; } set("postfix/procmail", $pmdefault); } if (-x "/usr/bin/procmail") { $noninteractive = (((input("low", "postfix/procmail"))[0]) == 30); } else { $noninteractive = 1; } if ($noninteractive) { $topstate = "mailbox_limit"; } else { $back = (((go())[0]) == 30); if ($back) { fset("postfix/mynetworks", "isdefault", "true"); fset("postfix/procmail", "isdefault", "true"); $topstate = "mynetworks"; } else { fset("postfix/procmail", "changed", "true"); $topstate = "mailbox_limit"; } } } if ($topstate eq "mailbox_limit") { $noninteractive = (((input("low", "postfix/mailbox_limit"))[0]) == 30); if ($noninteractive) { $topstate = "recipient_delim"; } else { $back = (((go())[0]) == 30); if ($back) { fset("postfix/procmail", "isdefault", "true"); fset("postfix/mailbox_limit", "isdefault", "true"); if (-x "/usr/bin/procmail") { $topstate = "procmail"; } else { fset("postfix/mynetworks", "isdefault", "true"); $topstate = "mynetworks"; } } else { fset("postfix/mailbox_limit", "changed", "true"); $topstate = "recipient_delim"; } } } if ($topstate eq "recipient_delim") { $noninteractive = (((input("low", "postfix/recipient_delim"))[0]) == 30); if ($noninteractive) { $topstate = "protocols"; } else { $back = (((go())[0]) == 30); if ($back) { fset("postfix/mailbox_limit", "isdefault", "true"); fset("postfix/recipient_delim", "isdefault", "true"); $topstate = "mailbox_limit"; } else { my $delim = get("postfix/recipient_delim"); if (length($delim) > 1) { fset("postfix/bad_recipient_delimiter","isdefault","true"); subst("postfix/bad_recipient_delimiter", "enteredstring", $delim); $noninteractive = (((input("low", "postfix/bad_recipient_delimiter"))[0]) == 30); fset("postfix/recipient_delim","isdefault","true"); # and do it again... } else { fset("postfix/recipient_delim", "changed", "true"); $topstate = "protocols"; } } } } if ($topstate eq "protocols") { if ((-x "/usr/sbin/postconf") && (-f "/etc/postfix/main.cf")) { my $protos; if (open my $fh, '-|', "postconf -hx inet_protocols") { $protos=<$fh>; close $fh; chomp $protos; set("postfix/protocols", $protos); } } elsif (fget("postfix/protocols", "isdefault") eq "true") { my $protos; if (-d "/proc/sys/net/ipv6" && -d "/proc/sys/net/ipv4") { $protos="all"; } elsif (-d "/proc/sys/net/ipv6") { $protos="ipv6"; } elsif (-d "/proc/sys/net/ipv4") { $protos="ipv4"; } set("postfix/protocols", $protos) if $protos; } $noninteractive = (((input("low", "postfix/protocols"))[0]) == 30); if ($noninteractive) { $topstate = "ending-setup"; } else { $back = (((go())[0]) == 30); if ($back) { fset("postfix/recipient_delim", "isdefault", "true"); fset("postfix/protocols", "isdefault", "true"); $topstate = "recipient_delim"; } else { fset("postfix/protocols", "changed", "true"); $topstate = "ending-setup"; } } } if ($topstate eq "ending-setup") { if ($ARGV[0] eq "reconfigure") { # touch /var/lib/postfix/reload if (sysopen my $fh, "/var/spool/postfix/reload", O_CREAT) { close $fh; } } else { # touch /var/lib/postfix/restart if (sysopen my $fh, "/var/spool/postfix/restart", O_CREAT) { close $fh; } } $topstate = "done"; } } # end TOPSTATE } # end while ($topstate ne q(done))