1 package PMG
::Config
::Base
;
8 use PVE
::JSONSchema
qw(get_standard_option);
9 use PVE
::SectionConfig
;
11 use base
qw(PVE::SectionConfig);
15 type
=> { description
=> "Section type." },
17 description
=> "Secion ID.",
18 type
=> 'string', format
=> 'pve-configid',
27 sub format_section_header
{
28 my ($class, $type, $sectionId) = @_;
30 die "internal error ($type ne $sectionId)" if $type ne $sectionId;
32 return "section: $type\n";
36 sub parse_section_header
{
37 my ($class, $line) = @_;
39 if ($line =~ m/^section:\s*(\S+)\s*$/) {
41 my $errmsg = undef; # set if you want to skip whole section
42 eval { PVE
::JSONSchema
::pve_verify_configid
($section); };
44 my $config = {}; # to return additional attributes
45 return ($section, $section, $errmsg, $config);
50 package PMG
::Config
::Admin
;
55 use base
qw(PMG::Config::Base);
64 description
=> "Send daily reports.",
69 description
=> "Demo mode - do not start SMTP filter.",
74 description
=> "Administrator E-Mail address.",
75 type
=> 'string', format
=> 'email',
76 default => 'admin@domain.tld',
79 description
=> "HTTP proxy port.",
85 description
=> "HTTP proxy server address.",
89 description
=> "HTTP proxy user name.",
93 description
=> "HTTP proxy password.",
101 dailyreport
=> { optional
=> 1 },
102 demo
=> { optional
=> 1 },
103 email
=> { optional
=> 1 },
104 proxyport
=> { optional
=> 1 },
105 proxyserver
=> { optional
=> 1 },
106 proxyuser
=> { optional
=> 1 },
107 proxypassword
=> { optional
=> 1 },
111 package PMG
::Config
::Spam
;
116 use base
qw(PMG::Config::Base);
125 description
=> "This option is used to specify which languages are considered OK for incoming mail.",
127 pattern
=> '(all|([a-z][a-z])+( ([a-z][a-z])+)*)',
131 description
=> "Whether to use the naive-Bayesian-style classifier.",
136 description
=> "Use the Auto-Whitelist plugin.",
141 description
=> "Whether to use Razor2, if it is available.",
146 description
=> "Enable OCR to scan pictures.",
150 wl_bounce_relays
=> {
151 description
=> "Whitelist legitimate bounce relays.",
155 description
=> "Additional score for bounce mails.",
162 description
=> "Enable real time blacklists (RBL) checks.",
167 description
=> "Maximum size of spam messages in bytes.",
177 use_awl
=> { optional
=> 1 },
178 use_razor
=> { optional
=> 1 },
179 use_ocr
=> { optional
=> 1 },
180 wl_bounce_relays
=> { optional
=> 1 },
181 languages
=> { optional
=> 1 },
182 use_bayes
=> { optional
=> 1 },
183 bounce_score
=> { optional
=> 1 },
184 rbl_checks
=> { optional
=> 1 },
185 maxspamsize
=> { optional
=> 1 },
189 package PMG
::Config
::ClamAV
;
194 use base
qw(PMG::Config::Base);
203 description
=> "ClamAV database mirror server.",
205 default => 'database.clamav.net',
207 archiveblockencrypted
=> {
208 description
=> "Wether to block encrypted archives. Mark encrypted archives as viruses.",
213 description
=> "Nested archives are scanned recursively, e.g. if a ZIP archive contains a TAR file, all files within it will also be scanned. This options specifies how deeply the process should be continued. Warning: setting this limit too high may result in severe damage to the system.",
219 description
=> "Number of files to be scanned within an archive, a document, or any other kind of container. Warning: disabling this limit or setting it too high may result in severe damage to the system.",
225 description
=> "Files larger than this limit won't be scanned.",
231 description
=> "Sets the maximum amount of data to be scanned for each input file.",
234 default => 100000000,
237 description
=> "This option sets the lowest number of Credit Card or Social Security numbers found in a file to generate a detect.",
247 archiveblockencrypted
=> { optional
=> 1 },
248 archivemaxrec
=> { optional
=> 1 },
249 archivemaxfiles
=> { optional
=> 1 },
250 archivemaxsize
=> { optional
=> 1 },
251 maxscansize
=> { optional
=> 1 },
252 dbmirror
=> { optional
=> 1 },
253 maxcccount
=> { optional
=> 1 },
257 package PMG
::Config
::Mail
;
262 use PVE
::ProcFSTools
;
264 use base
qw(PMG::Config::Base);
271 sub physical_memory
{
273 return $physicalmem if $physicalmem;
275 my $info = PVE
::ProcFSTools
::read_meminfo
();
276 my $total = int($info->{memtotal
} / (1024*1024));
281 sub get_max_filters
{
282 # estimate optimal number of filter servers
286 my $memory = physical_memory
();
287 my $add_servers = int(($memory - 512)/$servermem);
288 $max_servers += $add_servers if $add_servers > 0;
289 $max_servers = 40 if $max_servers > 40;
291 return $max_servers - 2;
295 # estimate optimal number of smtpd daemons
297 my $max_servers = 25;
299 my $memory = physical_memory
();
300 my $add_servers = int(($memory - 512)/$servermem);
301 $max_servers += $add_servers if $add_servers > 0;
302 $max_servers = 100 if $max_servers > 100;
307 # estimate optimal number of proxpolicy servers
309 my $memory = physical_memory
();
310 $max_servers = 5 if $memory >= 500;
317 description
=> "SMTP port number for outgoing mail (trusted).",
324 description
=> "SMTP port number for incoming mail (untrusted). This must be a different number than 'int_port'.",
331 description
=> "The default mail delivery transport (incoming mails).",
332 type
=> 'string', format
=> 'address',
335 description
=> "SMTP port number for relay host.",
342 description
=> "Disable MX lookups for default relay.",
347 description
=> "When set, all outgoing mails are deliverd to the specified smarthost.",
348 type
=> 'string', format
=> 'address',
351 description
=> "ESMTP banner.",
354 default => 'ESMTP Proxmox',
357 description
=> "Maximum number of pmg-smtp-filter processes.",
361 default => get_max_filters
(),
364 description
=> "Maximum number of pmgpolicy processes.",
368 default => get_max_policy
(),
371 description
=> "Maximum number of SMTP daemon processes (in).",
375 default => get_max_smtpd
(),
378 description
=> "Maximum number of SMTP daemon processes (out).",
382 default => get_max_smtpd
(),
384 conn_count_limit
=> {
385 description
=> "How many simultaneous connections any client is allowed to make to this service. To disable this feature, specify a limit of 0.",
391 description
=> "The maximal number of connection attempts any client is allowed to make to this service per minute. To disable this feature, specify a limit of 0.",
396 message_rate_limit
=> {
397 description
=> "The maximal number of message delivery requests that any client is allowed to make to this service per minute.To disable this feature, specify a limit of 0.",
403 description
=> "Hide received header in outgoing mails.",
408 description
=> "Maximum email size. Larger mails are rejected.",
411 default => 1024*1024*10,
414 description
=> "SMTP delay warning time (in hours).",
420 description
=> "Use Realtime Blacklists.",
425 description
=> "Enable TLS.",
430 description
=> "Enable TLS Logging.",
435 description
=> "Add TLS received header.",
440 description
=> "Use Sender Policy Framework.",
445 description
=> "Use Greylisting.",
450 description
=> "Use SMTP HELO tests.",
455 description
=> "Reject unknown clients.",
459 rejectunknownsender
=> {
460 description
=> "Reject unknown senders.",
465 description
=> "Enable receiver verification. The value spefifies the numerical reply code when the Postfix SMTP server rejects a recipient address.",
467 enum
=> ['450', '550'],
470 description
=> "Optional list of DNS white/blacklist domains (see postscreen_dnsbl_sites parameter).",
478 int_port
=> { optional
=> 1 },
479 ext_port
=> { optional
=> 1 },
480 smarthost
=> { optional
=> 1 },
481 relay
=> { optional
=> 1 },
482 relayport
=> { optional
=> 1 },
483 relaynomx
=> { optional
=> 1 },
484 dwarning
=> { optional
=> 1 },
485 max_smtpd_in
=> { optional
=> 1 },
486 max_smtpd_out
=> { optional
=> 1 },
487 greylist
=> { optional
=> 1 },
488 helotests
=> { optional
=> 1 },
489 use_rbl
=> { optional
=> 1 },
490 tls
=> { optional
=> 1 },
491 tlslog
=> { optional
=> 1 },
492 tlsheader
=> { optional
=> 1 },
493 spf
=> { optional
=> 1 },
494 maxsize
=> { optional
=> 1 },
495 banner
=> { optional
=> 1 },
496 max_filters
=> { optional
=> 1 },
497 max_policy
=> { optional
=> 1 },
498 hide_received
=> { optional
=> 1 },
499 rejectunknown
=> { optional
=> 1 },
500 rejectunknownsender
=> { optional
=> 1 },
501 conn_count_limit
=> { optional
=> 1 },
502 conn_rate_limit
=> { optional
=> 1 },
503 message_rate_limit
=> { optional
=> 1 },
504 verifyreceivers
=> { optional
=> 1 },
505 dnsbl_sites
=> { optional
=> 1 },
517 use PVE
::Tools
qw($IPV4RE $IPV6RE);
521 PMG
::Config
::Admin-
>register();
522 PMG
::Config
::Mail-
>register();
523 PMG
::Config
::Spam-
>register();
524 PMG
::Config
::ClamAV-
>register();
526 # initialize all plugins
527 PMG
::Config
::Base-
>init();
529 PVE
::JSONSchema
::register_format
(
530 'transport-domain', \
&pmg_verify_transport_domain
);
531 sub pmg_verify_transport_domain
{
532 my ($name, $noerr) = @_;
534 # like dns-name, but can contain leading dot
535 my $namere = "([a-zA-Z0-9]([a-zA-Z0-9\-]*[a-zA-Z0-9])?)";
537 if ($name !~ /^\.?(${namere}\.)*${namere}$/) {
538 return undef if $noerr;
539 die "value does not look like a valid transport domain\n";
547 my $class = ref($type) || $type;
549 my $cfg = PVE
::INotify
::read_file
("pmg.conf");
551 return bless $cfg, $class;
557 PVE
::INotify
::write_file
("pmg.conf", $self);
560 my $lockfile = "/var/lock/pmgconfig.lck";
563 my ($code, $errmsg) = @_;
565 my $p = PVE
::Tools
::lock_file
($lockfile, undef, $code);
567 $errmsg ?
die "$errmsg: $err" : die $err;
573 my ($self, $section, $key, $value) = @_;
575 my $pdata = PMG
::Config
::Base-
>private();
577 my $plugin = $pdata->{plugins
}->{$section};
578 die "no such section '$section'" if !$plugin;
580 if (defined($value)) {
581 my $tmp = PMG
::Config
::Base-
>check_value($section, $key, $value, $section, 0);
582 $self->{ids
}->{$section} = { type
=> $section } if !defined($self->{ids
}->{$section});
583 $self->{ids
}->{$section}->{$key} = PMG
::Config
::Base-
>decode_value($section, $key, $tmp);
585 if (defined($self->{ids
}->{$section})) {
586 delete $self->{ids
}->{$section}->{$key};
593 # get section value or default
595 my ($self, $section, $key) = @_;
597 my $pdata = PMG
::Config
::Base-
>private();
598 my $pdesc = $pdata->{propertyList
}->{$key};
599 die "no such property '$section/$key'\n"
600 if !(defined($pdesc) && defined($pdata->{options
}->{$section}) &&
601 defined($pdata->{options
}->{$section}->{$key}));
603 if (defined($self->{ids
}->{$section}) &&
604 defined(my $value = $self->{ids
}->{$section}->{$key})) {
608 return $pdesc->{default};
611 # get a whole section with default value
613 my ($self, $section) = @_;
615 my $pdata = PMG
::Config
::Base-
>private();
616 return undef if !defined($pdata->{options
}->{$section});
620 foreach my $key (keys %{$pdata->{options
}->{$section}}) {
622 my $pdesc = $pdata->{propertyList
}->{$key};
624 if (defined($self->{ids
}->{$section}) &&
625 defined(my $value = $self->{ids
}->{$section}->{$key})) {
626 $res->{$key} = $value;
629 $res->{$key} = $pdesc->{default};
635 # get a whole config with default values
639 my $pdata = PMG
::Config
::Base-
>private();
643 foreach my $type (keys %{$pdata->{plugins
}}) {
644 my $plugin = $pdata->{plugins
}->{$type};
645 $res->{$type} = $self->get_section($type);
652 my ($filename, $fh) = @_;
654 local $/ = undef; # slurp mode
656 my $raw = <$fh> if defined($fh);
658 return PMG
::Config
::Base-
>parse_config($filename, $raw);
662 my ($filename, $fh, $cfg) = @_;
664 my $raw = PMG
::Config
::Base-
>write_config($filename, $cfg);
666 PVE
::Tools
::safe_print
($filename, $fh, $raw);
669 PVE
::INotify
::register_file
('pmg.conf', "/etc/pmg/pmg.conf",
672 undef, always_call_parser
=> 1);
674 # parsers/writers for other files
676 my $domainsfilename = "/etc/pmg/domains";
678 sub postmap_pmg_domains
{
679 PMG
::Utils
::run_postmap
($domainsfilename);
682 sub read_pmg_domains
{
683 my ($filename, $fh) = @_;
689 while (defined(my $line = <$fh>)) {
691 next if $line =~ m/^\s*$/;
692 if ($line =~ m/^#(.*)\s*$/) {
696 if ($line =~ m/^(\S+)\s.*$/) {
698 $domains->{$domain} = {
699 domain
=> $domain, comment
=> $comment };
702 warn "parse error in '$filename': $line\n";
711 sub write_pmg_domains
{
712 my ($filename, $fh, $domains) = @_;
714 foreach my $domain (sort keys %$domains) {
715 my $comment = $domains->{$domain}->{comment
};
716 PVE
::Tools
::safe_print
($filename, $fh, "#$comment\n")
717 if defined($comment) && $comment !~ m/^\s*$/;
719 PVE
::Tools
::safe_print
($filename, $fh, "$domain 1\n");
723 PVE
::INotify
::register_file
('domains', $domainsfilename,
726 undef, always_call_parser
=> 1);
728 my $mynetworks_filename = "/etc/pmg/mynetworks";
730 sub postmap_pmg_mynetworks
{
731 PMG
::Utils
::run_postmap
($mynetworks_filename);
734 sub read_pmg_mynetworks
{
735 my ($filename, $fh) = @_;
741 while (defined(my $line = <$fh>)) {
743 next if $line =~ m/^\s*$/;
744 if ($line =~ m!^((?:$IPV4RE|$IPV6RE))/(\d+)\s*(?:#(.*)\s*)?$!) {
745 my ($network, $prefix_size, $comment) = ($1, $2, $3);
746 my $cidr = "$network/${prefix_size}";
747 $mynetworks->{$cidr} = {
749 network_address
=> $network,
750 prefix_size
=> $prefix_size,
751 comment
=> $comment // '',
754 warn "parse error in '$filename': $line\n";
762 sub write_pmg_mynetworks
{
763 my ($filename, $fh, $mynetworks) = @_;
765 foreach my $cidr (sort keys %$mynetworks) {
766 my $data = $mynetworks->{$cidr};
767 my $comment = $data->{comment
} // '*';
768 PVE
::Tools
::safe_print
($filename, $fh, "$cidr #$comment\n");
772 PVE
::INotify
::register_file
('mynetworks', $mynetworks_filename,
773 \
&read_pmg_mynetworks
,
774 \
&write_pmg_mynetworks
,
775 undef, always_call_parser
=> 1);
777 my $transport_map_filename = "/etc/pmg/transport";
779 sub postmap_pmg_transport
{
780 PMG
::Utils
::run_postmap
($transport_map_filename);
783 sub read_transport_map
{
784 my ($filename, $fh) = @_;
786 return [] if !defined($fh);
792 while (defined(my $line = <$fh>)) {
794 next if $line =~ m/^\s*$/;
795 if ($line =~ m/^#(.*)\s*$/) {
800 my $parse_error = sub {
802 warn "parse error in '$filename': $line - $err";
806 if ($line =~ m/^(\S+)\s+smtp:(\S+):(\d+)\s*$/) {
807 my ($domain, $host, $port) = ($1, $2, $3);
809 eval { pmg_verify_transport_domain
($domain); };
811 $parse_error->($err);
815 if ($host =~ m/^\[(.*)\]$/) {
820 eval { PVE
::JSONSchema
::pve_verify_address
($host); };
822 $parse_error->($err);
833 $res->{$domain} = $data;
836 $parse_error->('wrong format');
843 sub write_transport_map
{
844 my ($filename, $fh, $tmap) = @_;
848 foreach my $domain (sort keys %$tmap) {
849 my $data = $tmap->{$domain};
851 my $comment = $data->{comment
};
852 PVE
::Tools
::safe_print
($filename, $fh, "#$comment\n")
853 if defined($comment) && $comment !~ m/^\s*$/;
855 my $use_mx = $data->{use_mx
};
856 $use_mx = 0 if $data->{host
} =~ m/^(?:$IPV4RE|$IPV6RE)$/;
859 PVE
::Tools
::safe_print
(
860 $filename, $fh, "$data->{domain} smtp:$data->{host}:$data->{port}\n");
862 PVE
::Tools
::safe_print
(
863 $filename, $fh, "$data->{domain} smtp:[$data->{host}]:$data->{port}\n");
868 PVE
::INotify
::register_file
('transport', $transport_map_filename,
869 \
&read_transport_map
,
870 \
&write_transport_map
,
871 undef, always_call_parser
=> 1);
873 # config file generation using templates
875 sub get_template_vars
{
878 my $vars = { pmg
=> $self->get_config() };
880 my $nodename = PVE
::INotify
::nodename
();
881 my $int_ip = PMG
::Cluster
::remote_node_ip
($nodename);
882 my $int_net_cidr = PMG
::Utils
::find_local_network_for_ip
($int_ip);
883 $vars->{ipconfig
}->{int_ip
} = $int_ip;
884 # $vars->{ipconfig}->{int_net_cidr} = $int_net_cidr;
886 my $transportnets = [];
888 my $tmap = PVE
::INotify
::read_file
('transport');
889 foreach my $domain (sort keys %$tmap) {
890 my $data = $tmap->{$domain};
891 my $host = $data->{host
};
892 if ($host =~ m/^$IPV4RE$/) {
893 push @$transportnets, "$host/32";
894 } elsif ($host =~ m/^$IPV6RE$/) {
895 push @$transportnets, "[$host]/128";
899 $vars->{postfix
}->{transportnets
} = join(' ', @$transportnets);
901 my $mynetworks = [ '127.0.0.0/8', '[::1]/128' ];
902 push @$mynetworks, @$transportnets;
903 push @$mynetworks, $int_net_cidr;
904 push @$mynetworks, 'hash:/etc/pmg/mynetworks';
906 my $netlist = PVE
::INotify
::read_file
('mynetworks');
907 # add default relay to mynetworks
908 if (my $relay = $self->get('mail', 'relay')) {
909 if ($relay =~ m/^$IPV4RE$/) {
910 push @$mynetworks, "$relay/32";
911 } elsif ($relay =~ m/^$IPV6RE$/) {
912 push @$mynetworks, "[$relay]/128";
914 # DNS name - do nothing ?
918 $vars->{postfix
}->{mynetworks
} = join(' ', @$mynetworks);
921 $usepolicy = 1 if $self->get('mail', 'greylist') ||
922 $self->get('mail', 'spf') || $self->get('mail', 'use_rbl');
923 $vars->{postfix
}->{usepolicy
} = $usepolicy;
925 my $resolv = PVE
::INotify
::read_file
('resolvconf');
926 $vars->{dns
}->{hostname
} = $nodename;
927 $vars->{dns
}->{domain
} = $resolv->{search
};
932 # rewrite file from template
933 # return true if file has changed
934 sub rewrite_config_file
{
935 my ($self, $tmplname, $dstfn) = @_;
937 my $demo = $self->get('admin', 'demo');
939 my $srcfn = ($tmplname =~ m
|^.?
/|) ?
940 $tmplname : "/var/lib/pmg/templates/$tmplname";
943 my $demosrc = "$srcfn.demo";
944 $srcfn = $demosrc if -f
$demosrc;
947 my ($perm, $uid, $gid);
949 my $srcfd = IO
::File-
>new ($srcfn, "r")
950 || die "cant read template '$srcfn' - $!: ERROR";
952 if ($dstfn eq '/etc/fetchmailrc') {
953 (undef, undef, $uid, $gid) = getpwnam('fetchmail');
955 } elsif ($dstfn eq '/etc/clamav/freshclam.conf') {
956 # needed if file contains a HTTPProxyPasswort
958 $uid = getpwnam('clamav');
959 $gid = getgrnam('adm');
963 my $template = Template-
>new({});
965 my $vars = $self->get_template_vars();
969 $template->process($srcfd, $vars, \
$output) ||
970 die $template->error();
974 my $old = PVE
::Tools
::file_get_contents
($dstfn, 128*1024) if -f
$dstfn;
976 return 0 if defined($old) && ($old eq $output); # no change
978 PVE
::Tools
::file_set_contents
($dstfn, $output, $perm);
980 if (defined($uid) && defined($gid)) {
981 chown($uid, $gid, $dstfn);
987 # rewrite spam configuration
988 sub rewrite_config_spam
{
991 my $use_awl = $self->get('spam', 'use_awl');
992 my $use_bayes = $self->get('spam', 'use_bayes');
993 my $use_razor = $self->get('spam', 'use_razor');
997 # delete AW and bayes databases if those features are disabled
999 $changes = 1 if unlink '/root/.spamassassin/auto-whitelist';
1003 $changes = 1 if unlink '/root/.spamassassin/bayes_journal';
1004 $changes = 1 if unlink '/root/.spamassassin/bayes_seen';
1005 $changes = 1 if unlink '/root/.spamassassin/bayes_toks';
1008 # make sure we have a custom.cf file (else cluster sync fails)
1009 IO
::File-
>new('/etc/mail/spamassassin/custom.cf', 'a', 0644);
1011 $changes = 1 if $self->rewrite_config_file(
1012 'local.cf.in', '/etc/mail/spamassassin/local.cf');
1014 $changes = 1 if $self->rewrite_config_file(
1015 'init.pre.in', '/etc/mail/spamassassin/init.pre');
1017 $changes = 1 if $self->rewrite_config_file(
1018 'v310.pre.in', '/etc/mail/spamassassin/v310.pre');
1020 $changes = 1 if $self->rewrite_config_file(
1021 'v320.pre.in', '/etc/mail/spamassassin/v320.pre');
1024 mkdir "/root/.razor";
1026 $changes = 1 if $self->rewrite_config_file(
1027 'razor-agent.conf.in', '/root/.razor/razor-agent.conf');
1029 if (! -e
'/root/.razor/identity') {
1032 PVE
::Tools
::run_command
(['razor-admin', '-discover'], timeout
=> $timeout);
1033 PVE
::Tools
::run_command
(['razor-admin', '-register'], timeout
=> $timeout);
1036 syslog
('info', msgquote
("registering razor failed: $err")) if $err;
1043 # rewrite ClamAV configuration
1044 sub rewrite_config_clam
{
1047 return $self->rewrite_config_file(
1048 'clamd.conf.in', '/etc/clamav/clamd.conf');
1051 sub rewrite_config_freshclam
{
1054 return $self->rewrite_config_file(
1055 'freshclam.conf.in', '/etc/clamav/freshclam.conf');
1058 sub rewrite_config_postgres
{
1061 my $pgconfdir = "/etc/postgresql/9.6/main";
1065 $changes = 1 if $self->rewrite_config_file(
1066 'pg_hba.conf.in', "$pgconfdir/pg_hba.conf");
1068 $changes = 1 if $self->rewrite_config_file(
1069 'postgresql.conf.in', "$pgconfdir/postgresql.conf");
1074 # rewrite /root/.forward
1075 sub rewrite_dot_forward
{
1078 my $dstfn = '/root/.forward';
1080 my $email = $self->get('admin', 'email');
1083 if ($email && $email =~ m/\s*(\S+)\s*/) {
1086 # empty .forward does not forward mails (see man local)
1089 my $old = PVE
::Tools
::file_get_contents
($dstfn, 128*1024) if -f
$dstfn;
1091 return 0 if defined($old) && ($old eq $output); # no change
1093 PVE
::Tools
::file_set_contents
($dstfn, $output);
1098 # rewrite /etc/postfix/*
1099 sub rewrite_config_postfix
{
1102 # make sure we have required files (else postfix start fails)
1103 postmap_pmg_domains
();
1104 postmap_pmg_transport
();
1105 postmap_pmg_mynetworks
();
1107 IO
::File-
>new($transport_map_filename, 'a', 0644);
1111 if ($self->get('mail', 'tls')) {
1113 PMG
::Utils
::gen_proxmox_tls_cert
();
1115 syslog
('info', msgquote
("generating certificate failed: $@")) if $@;
1118 $changes = 1 if $self->rewrite_config_file(
1119 'main.cf.in', '/etc/postfix/main.cf');
1121 $changes = 1 if $self->rewrite_config_file(
1122 'master.cf.in', '/etc/postfix/master.cf');
1124 #rewrite_config_transports ($class);
1125 #rewrite_config_whitelist ($class);
1126 #rewrite_config_tls_policy ($class);
1128 # make sure aliases.db is up to date
1129 system('/usr/bin/newaliases');
1134 sub rewrite_config
{
1135 my ($self, $restart_services) = @_;
1137 if ($self->rewrite_config_postfix() && $restart_services) {
1138 PMG
::Utils
::service_cmd
('postfix', 'restart');
1141 if ($self->rewrite_dot_forward() && $restart_services) {
1142 # no need to restart anything
1145 if ($self->rewrite_config_postgres() && $restart_services) {
1146 # do nothing (too many side effects)?
1147 # does not happen anyways, because config does not change.
1150 if ($self->rewrite_config_spam() && $restart_services) {
1151 PMG
::Utils
::service_cmd
('pmg-smtp-filter', 'restart');
1154 if ($self->rewrite_config_clam() && $restart_services) {
1155 PMG
::Utils
::service_cmd
('clamav-daemon', 'restart');
1158 if ($self->rewrite_config_freshclam() && $restart_services) {
1159 PMG
::Utils
::service_cmd
('clamav-freshclam', 'restart');