Merge pull request #2741 from webmin/dev/postfix-tests-and-perlcritic

Postfix tests, perlcritic, strict/warnings, bugfixes
This commit is contained in:
Jamie Cameron
2026-05-24 13:10:38 -07:00
committed by GitHub
72 changed files with 954 additions and 404 deletions

View File

@@ -1,5 +1,8 @@
require 'postfix-lib.pl';
require 'postfix-lib.pl'; ## no critic
use strict;
use warnings;
our (@acl_pages, %in, %text);
@acl_pages = ("resource", "address_rewriting", "aliases", "general",
"canonical", "virtual", "transport", "relocated", "header",
"body", "bcc", "dependent", "sni", "local_delivery", "smtpd",
@@ -9,8 +12,7 @@ require 'postfix-lib.pl';
# Print the form for security options of postfix module
sub acl_security_form
{
local $o;
foreach $o (@acl_pages) {
foreach my $o (@acl_pages) {
print &ui_table_row($text{'acl_'.$o} || $o,
&ui_yesno_radio($o, $_[0]->{$o} ? 1 : 0));
}
@@ -23,8 +25,7 @@ print &ui_table_row($text{'acl_dir'},
# Parse the form for security options for the postfix module
sub acl_security_save
{
local $o;
foreach $o (@acl_pages) {
foreach my $o (@acl_pages) {
$_[0]->{$o} = $in{$o};
}
$_[0]->{'dir'} = $in{'dir'};

View File

@@ -7,7 +7,10 @@
#
# << Here are all options seen in Postfix sample-rewrite.cf >>
require './postfix-lib.pl';
require './postfix-lib.pl'; ## no critic
use strict;
use warnings;
our ($default, $no_, $none, %access, %text);
$access{'address_rewriting'} || &error($text{'address_rewriting_ecannot'});
&ui_print_header(undef, $text{'address_rewriting_title'}, "");

View File

@@ -8,7 +8,10 @@
# << Here are all options seen in Postfix sample-aliases.cf >>
require './postfix-lib.pl';
require './postfix-lib.pl'; ## no critic
use strict;
use warnings;
our ($al, $anum, $astr, $i, $lines, $mid, $midline, %access, @aline, %config, @grid, @links, %text);
$access{'aliases'} || &error($text{'aliases_ecannot'});
&ui_print_header(undef, $text{'aliases_title'}, "", "aliases");
@@ -93,8 +96,8 @@ foreach my $a (@_) {
push(@cols, "<a href=\"edit_alias.cgi?num=$a->{'num'}\">".
($a->{'enabled'} ? "" : "<i>").&html_escape($a->{'name'}).
($a->{'enabled'} ? "" : "</i>")."</a>");
local $vstr;
foreach $v (@{$a->{'values'}}) {
my $vstr;
foreach my $v (@{$a->{'values'}}) {
($anum, $astr) = &alias_type($v);
$vstr .= &text("aliases_type$anum",
"<tt>".&html_escape($astr)."</tt>")."<br>\n";

View File

@@ -1,4 +1,5 @@
use strict;
use warnings;
do 'postfix-lib.pl';
# backup_config_files()
@@ -12,21 +13,21 @@ return &get_all_config_files();
# Called before the files are actually read
sub pre_backup
{
return undef;
return;
}
# post_backup(&files)
# Called after the files are actually read
sub post_backup
{
return undef;
return;
}
# pre_restore(&files)
# Called before the files are restored from a backup
sub pre_restore
{
return undef;
return;
}
# post_restore(&files)
@@ -36,7 +37,7 @@ sub post_restore
if (&is_postfix_running()) {
return &reload_postfix();
}
return undef;
return;
}
1;

View File

@@ -1,6 +1,9 @@
#!/usr/local/bin/perl
require './postfix-lib.pl';
require './postfix-lib.pl'; ## no critic
use strict;
use warnings;
our (%access, %in, %text);
$access{'bcc'} || &error($text{'bcc_ecannot'});
&ui_print_header(undef, $text{'bcc_title'}, "", "bcc");

View File

@@ -8,7 +8,10 @@
# << Here are all options seen in Postfix sample-virtual.cf >>
require './postfix-lib.pl';
require './postfix-lib.pl'; ## no critic
use strict;
use warnings;
our (%access, %text);
&ReadParse();
$access{'body'} || &error($text{'body_ecannot'});

View File

@@ -8,7 +8,10 @@
# << Here are all options seen in Postfix sample-canonical.cf >>
require './postfix-lib.pl';
require './postfix-lib.pl'; ## no critic
use strict;
use warnings;
our (%access, %text);
$access{'canonical'} || &error($text{'canonical_ecannot'});
&ui_print_header(undef, $text{'canonical_title'}, "", "canonical");

View File

@@ -5,7 +5,10 @@
#
# Edit one category of canonical maps
require './postfix-lib.pl';
require './postfix-lib.pl'; ## no critic
use strict;
use warnings;
our (%in, %text);
&ReadParse();
&ui_print_header(undef, $text{'canonical_edit_title'}, "", "canonical");

View File

@@ -2,7 +2,10 @@
# A single page just for editing smtpd_client_restrictions
# XXX editing access maps?
require './postfix-lib.pl';
require './postfix-lib.pl'; ## no critic
use strict;
use warnings;
our ($default, $has_client_access, $no_, $none, $vals, %access, %done, @grid, %opts, @opts, @rest, %text, @v);
$access{'client'} || &error($text{'client_ecannot'});
&ui_print_header(undef, $text{'client_title'}, "");
@@ -24,15 +27,15 @@ for(my $i=0; $i<@opts; $i++) {
# Add binary restrictions to list
@grid = ( );
%done = ( );
foreach $r (&list_client_restrictions()) {
foreach my $r (&list_client_restrictions()) {
push(@grid, &ui_checkbox("client", $r, $text{'sasl_'.$r},
defined($opts{$r})), undef);
$done{$r} = 1;
}
# Add restrictions with values
foreach $r (&list_multi_client_restrictions()) {
@v = @{$opts{$r}};
foreach my $r (&list_multi_client_restrictions()) {
@v = $opts{$r} ? @{$opts{$r}} : ();
$vals = undef;
if (scalar(@v)) {
$vals = join(" ", map { $opts[$_+1] } @v);
@@ -43,7 +46,7 @@ foreach $r (&list_multi_client_restrictions()) {
($r eq "check_client_access" ?
" ".&map_chooser_button("value_$r", $r) : ""));
$done{$r} = 1;
foreach $v (@v) {
foreach my $v (@v) {
$done{$opts[$v+1]} = 1;
}
if ($r eq "check_client_access" && @v) {

View File

@@ -7,7 +7,10 @@
#
# << Here are all options seen in Postfix sample-debug.cf >>
require './postfix-lib.pl';
require './postfix-lib.pl'; ## no critic
use strict;
use warnings;
our ($default, $no_, $none, %access, %text);
$access{'debug'} || &error($text{'debug_ecannot'});

View File

@@ -1,8 +1,11 @@
#!/usr/local/bin/perl
# Delete several mail aliases
require './postfix-lib.pl';
require './aliases-lib.pl';
require './postfix-lib.pl'; ## no critic
use strict;
use warnings;
our ($alias, $err, %access, @afiles, @aliases, @d, @delaliases, %in, %text);
require './aliases-lib.pl'; ## no critic
&ReadParse();
&error_setup($text{'adelete_err'});
$access{'aliases'} || &error($text{'aliases_ecannot'});
@@ -13,7 +16,7 @@ $access{'aliases'} || &error($text{'aliases_ecannot'});
@d = split(/\0/, $in{'d'});
@d || &error($text{'adelete_enone'});
@aliases = &list_postfix_aliases();
foreach $d (@d) {
foreach my $d (@d) {
($alias) = grep { $_->{'name'} eq $d } @aliases;
if ($alias) {
push(@delaliases, $alias);
@@ -21,7 +24,7 @@ foreach $d (@d) {
}
# Delete the aliases
foreach $alias (@delaliases) {
foreach my $alias (@delaliases) {
&delete_postfix_alias($alias);
}
&unlock_alias_files(\@afiles);

View File

@@ -1,7 +1,10 @@
#!/usr/local/bin/perl
# Delete multiple mappings
require './postfix-lib.pl';
require './postfix-lib.pl'; ## no critic
use strict;
use warnings;
our ($err, $map, $maps, @d, %in, %text);
&ReadParse();
&error_setup($text{'delete_err'});
@@ -9,7 +12,7 @@ require './postfix-lib.pl';
@d || &error($text{'delete_enone'});
$maps = &get_maps($in{'map_name'});
foreach $d (@d) {
foreach my $d (@d) {
($map) = grep { $_->{'name'} eq $d } @$maps;
if ($map) {
&lock_file($map->{'file'});

View File

@@ -2,27 +2,30 @@
# delete_queues.cgi
# Delete multiple messages from the postfix queue
require './postfix-lib.pl';
require './postfix-lib.pl'; ## no critic
use strict;
use warnings;
our ($postfix_version, %access, %config, @files, %in, @qfiles, %text);
$access{'mailq'} || &error($text{'mailq_ecannot'});
&ReadParse();
if ($in{'move'}) {
# Re-queuing messages
foreach $f (split(/\0/, $in{'file'})) {
foreach my $f (split(/\0/, $in{'file'})) {
&system_logged("$config{'postfix_super_command'} -r ".
quotemeta($f)." >/dev/null 2>&1 </dev/null");
}
}
elsif ($in{'hold'}) {
# Holding messages
foreach $f (split(/\0/, $in{'file'})) {
foreach my $f (split(/\0/, $in{'file'})) {
&system_logged("$config{'postfix_super_command'} -h ".
quotemeta($f)." >/dev/null 2>&1 </dev/null");
}
}
elsif ($in{'unhold'}) {
# Un-holding messages
foreach $f (split(/\0/, $in{'file'})) {
foreach my $f (split(/\0/, $in{'file'})) {
&system_logged("$config{'postfix_super_command'} -H ".
quotemeta($f)." >/dev/null 2>&1 </dev/null");
}
@@ -41,7 +44,7 @@ else {
if (&compare_version_numbers($postfix_version, 1.1) < 0) {
@qfiles = &recurse_files($config{'mailq_dir'});
}
foreach $f (@files) {
foreach my $f (@files) {
$f =~ /^[A-Za-z0-9]+$/ || next;
if (&compare_version_numbers($postfix_version, 1.1) >= 0) {
&system_logged("$config{'postfix_super_command'} -d ".quotemeta($f)." >/dev/null 2>&1 </dev/null");

View File

@@ -6,7 +6,10 @@
# Manages sender_dependent_default_transport_maps for Postfix
require './postfix-lib.pl';
require './postfix-lib.pl'; ## no critic
use strict;
use warnings;
our (%access, %text);
$access{'dependent'} || &error($text{'dependent_ecannot'});
&ui_print_header(undef, $text{'dependent_title'}, "", "dependent");

View File

@@ -2,8 +2,11 @@
# detach_queue.cgi
# View one attachment from a queued message
require './postfix-lib.pl';
require './boxes-lib.pl';
require './postfix-lib.pl'; ## no critic
use strict;
use warnings;
our ($attach, $mail, %access, %in, %text);
require './boxes-lib.pl'; ## no critic
&ReadParse();
$access{'mailq'} || &error($text{'mailq_ecannot'});

View File

@@ -3,7 +3,10 @@
# Display a form to edit a general access mapping table
# by Roberto Tecchio, 2005 (www.tecchio.net)
require './postfix-lib.pl';
require './postfix-lib.pl'; ## no critic
use strict;
use warnings;
our (%access, %in, %text);
$access{'smtpd'} || &error($text{'smtpd_ecannot'});
&ReadParse();

View File

@@ -5,15 +5,18 @@
#
# Edit an email alias
require './postfix-lib.pl';
require './postfix-lib.pl'; ## no critic
use strict;
use warnings;
our ($cancmt, %in, %text);
&ReadParse();
&ui_print_header(undef, $text{'edit_alias_title'}, "");
my @aliases = &list_postfix_aliases();
$a = $aliases[$in{'num'}] if (!$in{'new'});
my $alias = $in{'new'} ? undef : $aliases[$in{'num'}];
$cancmt = &can_map_comments("alias_maps");
&alias_form($a, !$cancmt);
&alias_form($alias, !$cancmt);
&ui_print_footer("", $text{'index_return'});

View File

@@ -5,7 +5,10 @@
#
# Edit a mapping
require './postfix-lib.pl';
require './postfix-lib.pl'; ## no critic
use strict;
use warnings;
our ($cb, $tb, %in, %text);
&ReadParse();
&ui_print_header(undef, $text{'edit_mapping_title'}, "");
@@ -26,7 +29,7 @@ else
my $mappingsaliases = &get_aliases();
my %alias;
foreach $trans (@{$aliases})
foreach my $trans (@{$mappingsaliases})
{
if ($trans->{'number'} == $num) { %alias = %{$trans}; }
}

View File

@@ -1,7 +1,10 @@
#!/usr/local/bin/perl
# Show a form for editing a mapping file
require './postfix-lib.pl';
require './postfix-lib.pl'; ## no critic
use strict;
use warnings;
our ($data, $file, %access, @files, %in, %text);
&ReadParse();
$access{'manual'} || &error($text{'manual_ecannot'});
&ui_print_header(undef, $text{'manual_title'}, "");

View File

@@ -5,7 +5,10 @@
#
# Edit a mapping
require './postfix-lib.pl';
require './postfix-lib.pl'; ## no critic
use strict;
use warnings;
our ($nfunc, $vfunc, $virtual_maps, %in, %text);
&ReadParse();
&ui_print_header(undef, $text{'edit_map_title'}, "");
@@ -28,7 +31,7 @@ else
my $maps = &get_maps($in{'map_name'});
my %map;
foreach $trans (@{$maps})
foreach my $trans (@{$maps})
{
if ($trans->{'number'} == $num) { %map = %{$trans}; }
}

View File

@@ -1,7 +1,10 @@
#!/usr/local/bin/perl
# Edit or create a server process
require './postfix-lib.pl';
require './postfix-lib.pl'; ## no critic
use strict;
use warnings;
our ($host, $master, $pmode, $prog, $wmode, $wused, %access, %in, %text);
$access{'master'} || &error($text{'master_ecannot'});
&ReadParse();
$master = &get_master_config();

View File

@@ -2,7 +2,10 @@
# flushq.cgi
# Run postqueue -f and display the output
require './postfix-lib.pl';
require './postfix-lib.pl'; ## no critic
use strict;
use warnings;
our ($cmd, $config_dir, $out, %config, %text);
&ui_print_unbuffered_header(undef, $text{'flushq_title'}, "");
$cmd = "$config{'postfix_queue_command'} -c $config_dir -f";

View File

@@ -7,7 +7,10 @@
#
# << Here are all options seen in Postfix sample-misc.cf >>
require './postfix-lib.pl';
require './postfix-lib.pl'; ## no critic
use strict;
use warnings;
our ($default, $no_, $none, $postfix_version, $v, %access, %text, @v);
$access{'general'} || &error($text{'general_ecannot'});

View File

@@ -8,7 +8,10 @@
# << Here are all options seen in Postfix sample-virtual.cf >>
require './postfix-lib.pl';
require './postfix-lib.pl'; ## no critic
use strict;
use warnings;
our (%access, %text);
&ReadParse();
$access{'header'} || &error($text{'header_ecannot'});

View File

@@ -23,7 +23,10 @@
#
require './postfix-lib.pl';
require './postfix-lib.pl'; ## no critic
use strict;
use warnings;
our ($err, $lnk, $module_config_directory, $module_name, $postfix_version, %access, %config, @oicons, @olinks, @onames, @otitles, %text);
&ui_print_header(undef, $text{'index_title'}, "", "intro", 1, 1, 0,
&help_search_link("postfix", "man", "doc", "google"),
@@ -31,9 +34,10 @@ require './postfix-lib.pl';
&text('index_version', $postfix_version) : undef);
# Save the version for use by other CGIs
&open_tempfile(VERSION, ">$module_config_directory/version", 0, 1);
&print_tempfile(VERSION, "$postfix_version\n");
&close_tempfile(VERSION);
my $verfh = "VERSION";
&open_tempfile($verfh, ">$module_config_directory/version", 0, 1);
&print_tempfile($verfh, "$postfix_version\n");
&close_tempfile($verfh);
# Verify the postfix control command
if (!&valid_postfix_command($config{'postfix_control_command'})) {
@@ -92,7 +96,7 @@ if ($config{'index_check'} && ($err = &check_postfix())) {
"master", "mailq", "postfinger", "boxes", "manual" );
$access{'boxes'} = &foreign_available("mailboxes");
foreach $oitem (@onames)
foreach my $oitem (@onames)
{
if ($access{$oitem}) {
push (@olinks, $oitem eq "boxes" ? "../mailboxes/"
@@ -101,8 +105,8 @@ foreach $oitem (@onames)
: $text{$oitem . "_title"});
if ($oitem eq 'mailq' && !$config{'mailq_count'}) {
# Count the queue
local @mqueue = &list_queue(0);
local $mcount = scalar(@mqueue);
my @mqueue = &list_queue(0);
my $mcount = scalar(@mqueue);
$otitles[$#otitles] .=
"<br>".&text('mailq_count', $mcount);
}

View File

@@ -1,6 +1,9 @@
# install_check.pl
use strict;
use warnings;
do 'postfix-lib.pl';
our (%config);
# is_installed(mode)
# For mode 1, returns 2 if the server is installed and configured for use by

View File

@@ -7,7 +7,10 @@
#
# << Here are all options seen in Postfix sample-ldap.cf >>
require './postfix-lib.pl';
require './postfix-lib.pl'; ## no critic
use strict;
use warnings;
our ($cb, $default, $ldap_timeout, $no_, $none, $tb, %access, %text);
$access{'ldap'} || &error($text{'ldap_ecannot'});

View File

@@ -7,7 +7,10 @@
#
# << Here are all options seen in Postfix sample-local.cf >>
require './postfix-lib.pl';
require './postfix-lib.pl'; ## no critic
use strict;
use warnings;
our ($default, $no_, $none, %access, %text);
$access{'local_delivery'} || &error($text{'local_delivery_ecannot'});

View File

@@ -1,13 +1,16 @@
# log_parser.pl
# Functions for parsing this module's logs
use strict;
use warnings;
do 'postfix-lib.pl';
our (%text);
# parse_webmin_log(user, script, action, type, object, &params)
# Converts logged information from this module into human-readable form
sub parse_webmin_log
{
local ($user, $script, $action, $type, $object, $p) = @_;
my ($user, $script, $action, $type, $object, $p) = @_;
if ($action eq 'delete' || $action eq 'modify' || $action eq 'create') {
return &text("log_${type}_${action}",
"<tt>".&html_escape($object)."</tt>") ||

View File

@@ -2,8 +2,11 @@
# mailq.cgi
# Display messages currently in the queue.
require './postfix-lib.pl';
require './boxes-lib.pl';
require './postfix-lib.pl'; ## no critic
use strict;
use warnings;
our ($e, $in, $s, %access, %config, %in, @qfiles, %text);
require './boxes-lib.pl'; ## no critic
&ReadParse();
$access{'mailq'} || &error($text{'mailq_ecannot'});

View File

@@ -2,8 +2,11 @@
# mailq_search.cgi
# Display some messages from the mail queue
require './postfix-lib.pl';
require './boxes-lib.pl';
require './postfix-lib.pl'; ## no critic
use strict;
use warnings;
our ($neg, %access, %in, @qfiles, %text);
require './boxes-lib.pl'; ## no critic
&ReadParse();
$access{'mailq'} || &error($text{'mailq_ecannot'});
&ui_print_header(undef, $text{'searchq_title'}, "");
@@ -17,7 +20,8 @@ $neg = ($in{'field'} =~ s/^!//);
$neg ? !$r : $r } @qfiles;
print "<p><b>",&text($in{'field'} =~ /^\!/ ? 'search_results3' :
'search_results2', scalar(@qfiles), "<tt>$in{'match'}</tt>"),"</b><p>\n";
'search_results2', scalar(@qfiles),
"<tt>".&html_escape($in{'match'})."</tt>"),"</b><p>\n";
if (@qfiles) {
# Show matching messages
&mailq_table(\@qfiles);

View File

@@ -1,7 +1,10 @@
#!/usr/local/bin/perl
# Show a page for manually editing the Postfix config file
require './postfix-lib.pl';
require './postfix-lib.pl'; ## no critic
use strict;
use warnings;
our ($data, %access, @files, %in, %text);
$access{'manual'} || &error($text{'cmanual_ecannot'});
&ReadParse();
&ui_print_header(undef, $text{'cmanual_title'}, "");

View File

@@ -1,7 +1,10 @@
#!/usr/local/bin/perl
# Update a manually edited config file
require './postfix-lib.pl';
require './postfix-lib.pl'; ## no critic
use strict;
use warnings;
our (%access, @files, %in, %text);
&error_setup($text{'cmanual_err'});
$access{'manual'} || &error($text{'cmanual_ecannot'});
&ReadParseMime();
@@ -15,9 +18,10 @@ if ($in{'file'} eq $files[0]) {
}
# Write to it
&open_lock_tempfile(DATA, ">$in{'file'}");
&print_tempfile(DATA, $in{'data'});
&close_tempfile(DATA);
my $datafh = "DATA";
&open_lock_tempfile($datafh, ">$in{'file'}");
&print_tempfile($datafh, $in{'data'});
&close_tempfile($datafh);
&webmin_log("manual", undef, $in{'file'});
&redirect("");

View File

@@ -1,7 +1,10 @@
#!/usr/local/bin/perl
# Show a form for selecting the source for a map
require './postfix-lib.pl';
require './postfix-lib.pl'; ## no critic
use strict;
use warnings;
our ($i, $lconf, $ltable, $mtable, $myconf, $postfix_version, $t, %in, @maps, @opts, @sources, %text);
&ReadParse();
&popup_header($text{'chooser_title'});
@@ -14,7 +17,7 @@ print &ui_form_start("map_chooser_save.cgi", "post");
print &ui_hidden("map", $in{'map'});
print &ui_hidden("mapname", $in{'mapname'});
$i = 0;
foreach $tv (@maps) {
foreach my $tv (@maps) {
print &ui_hidden_table_start(&text('chooser_header', $i+1),
"width=100%", 2, "section$i",
$tv->[0] || $i == 0, [ "width=30%" ]);

View File

@@ -1,7 +1,10 @@
#!/usr/local/bin/perl
# Show a form for selecting the source for a map
require './postfix-lib.pl';
require './postfix-lib.pl'; ## no critic
use strict;
use warnings;
our ($file, $i, $postfix_version, $str, $t, @files, %in, @maps, @newfiles, @oldmaps, %text);
&ReadParse();
&error_setup($text{'chooser_err'});
@oldmaps = &get_maps_types_files($in{'map'});
@@ -225,14 +228,14 @@ for($i=0; defined($t = $in{"type_".$i}); $i++) {
# Write out mysql and LDAP files
@files = &unique(@files);
@newfiles = map { !-r $_ } @files;
foreach $f (@files) {
foreach my $f (@files) {
&lock_file($f);
}
&flush_file_lines(@files);
foreach $f (@newfiles) {
foreach my $f (@newfiles) {
&set_ownership_permissions(undef, undef, 0700, $f);
}
foreach $f (@files) {
foreach my $f (@files) {
&unlock_file($f);
}

View File

@@ -1,7 +1,10 @@
#!/usr/local/bin/perl
# Show a table of Postfix server processes
require './postfix-lib.pl';
require './postfix-lib.pl'; ## no critic
use strict;
use warnings;
our ($master, %access, %text);
$access{'master'} || &error($text{'master_ecannot'});
&ui_print_header(undef, $text{'master_title'}, "", "master");
@@ -15,7 +18,7 @@ print &ui_columns_start([ $text{'master_name'},
$text{'master_unpriv'},
$text{'master_chroot'},
$text{'master_max'} ], "100%");
foreach $m (@$master) {
foreach my $m (@$master) {
print &ui_columns_row([
"<a href='edit_master.cgi?name=".&urlize($m->{'name'}).
"&type=".&urlize($m->{'type'})."&enabled=$m->{'enabled'}'>".

View File

@@ -2,7 +2,11 @@
# postfinger.cgi
# check postfix configuration
require './postfix-lib.pl';
require './postfix-lib.pl'; ## no critic
use strict;
use warnings;
our ($Defaultsinmain, $err, $Libraries, $Locking, $Main, $Master, $Package, $Permissions, $postf1, $postf2, $postf3, $postf4, $postf5, $postf6, $postf7, $postf8, $postfix_version, $System, $Tables, $Warn, %access, %config, %text);
my $mailq;
&ReadParse();
@@ -38,12 +42,12 @@ if ($System eq 1 ) {
print "</td></tr>";
print "</table><br />";
print "<table border='0' cellpadding='3' width='600' align='center'>";
open(MAILQ, "/bin/hostname 2>/dev/null |");
while (my $hostname = <MAILQ>) { print "<tr><td class='e'>Hostname </td><td class='v'>$hostname</td></tr>"; }
close(MAILQ);
open(MAILQ, "/bin/uname -a 2>/dev/null |");
while (my $uname = <MAILQ>) { print "<tr><td class='e'>System </td><td class='v'>$uname</td></tr>"; }
close(MAILQ);
open($mailq, "-|", "/bin/hostname 2>/dev/null");
while (my $hostname = <$mailq>) { print "<tr><td class='e'>Hostname </td><td class='v'>$hostname</td></tr>"; }
close($mailq);
open($mailq, "-|", "/bin/uname -a 2>/dev/null");
while (my $uname = <$mailq>) { print "<tr><td class='e'>System </td><td class='v'>$uname</td></tr>"; }
close($mailq);
}
print "</table><br />";
}
@@ -51,10 +55,10 @@ if ($System eq 1 ) {
if ($Locking eq 1 ) {
print '<h1 align="center">Mailbox locking methods</h1>';
print '<table border="0" cellpadding="0" width="600" align="center">';
open(MAILQ, "$config{'postfix_config_command'} -l 2>/dev/null |");
while (my $locking_methods = <MAILQ>) {
open($mailq, "-|", "$config{'postfix_config_command'} -l 2>/dev/null");
while (my $locking_methods = <$mailq>) {
print "<tr><td class='v'><center><b>$locking_methods</b></center></td></tr>"; }
close(MAILQ);
close($mailq);
print "</table><br />";
}
@@ -62,10 +66,10 @@ if ($Tables eq 1 ) {
print '<h1 align="center">Supported Lookup Tables</h1>';
print '<table border="0" cellpadding="0" width="600" align="center">';
# print '<center><b>--Supported Lookup tables--</b></center><br>';
open(MAILQ, "$config{'postfix_config_command'} -m 2>/dev/null |");
while (my $lookup_tables = <MAILQ>) {
open($mailq, "-|", "$config{'postfix_config_command'} -m 2>/dev/null");
while (my $lookup_tables = <$mailq>) {
print "<tr><td class='v'><center><b>$lookup_tables</b></center></td></tr>"; }
close(MAILQ);
close($mailq);
print "</table><br />";
}
@@ -82,12 +86,12 @@ if ($Main eq 1 ) {
print '<h1 align="center">main.cf</h1><br><h2 align="center">non-default parameters</h2>';
print '<table border="0" cellpadding="2" width="600" align="center">';
# print '<center><b>--main.cf non-default parameters--</b></center><br>';
open(MAILQ, "/usr/bin/comm -13 postfinger.$$.d postfinger.$$.n 2>/dev/null |");
while (my $postfinger = <MAILQ>) {
open($mailq, "-|", "/usr/bin/comm -13 postfinger.$$.d postfinger.$$.n 2>/dev/null");
while (my $postfinger = <$mailq>) {
($postf1,$postf2)=split(/=/,$postfinger,2);
print "<tr><td class='e'><b>$postf1</b></td>";
print "<td class='v'>$postf2</td></tr>"; }
close(MAILQ);
close($mailq);
print "</table><br />";
}
@@ -95,12 +99,12 @@ if ($Defaultsinmain eq 1 ) {
print '<h1 align="center">main.cf</h1><br><h2 align="center">parameters defined as per defaults</h2>';
print '<table border="0" cellpadding="2" width="600" align="center">';
# print '<center><b>--main.cf parameters defined as per defaults--</b></center><br>';
open(MAILQ, "/usr/bin/comm -12 postfinger.$$.d postfinger.$$.n 2>/dev/null |");
while (my $postfinger = <MAILQ>) {
open($mailq, "-|", "/usr/bin/comm -12 postfinger.$$.d postfinger.$$.n 2>/dev/null");
while (my $postfinger = <$mailq>) {
($postf1,$postf2)=split(/=/,$postfinger,2);
print "<tr><td class='e'><b>$postf1</b></td>";
print "<td class='v'>$postf2</td></tr>"; }
close(MAILQ);
close($mailq);
print "</table><br />";
}
unlink "postfinger.*.d, postfinger.*.n";
@@ -113,8 +117,8 @@ if ($Master eq 1 ) {
"<td class='v'><b>private</b></td><td class='v'><b>unpriv</b></td>",
"<td class='v'><b>chroot</b></td><td class='v'><b>wakeup</b></td>",
"<td class='v'><b>maxproc</b></td><td class='v'><b>command + args</b></td></tr>";
open(MAILQ, "/bin/cat `$config{'postfix_config_command'} -h config_directory`/master.cf 2>/dev/null |");
while (my $postfinger = <MAILQ>) {
open($mailq, "-|", "/bin/cat `$config{'postfix_config_command'} -h config_directory`/master.cf 2>/dev/null");
while (my $postfinger = <$mailq>) {
($postf1,$postf2,$postf3,$postf4,$postf5,$postf6,$postf7,$postf8)=split(/\s+/,$postfinger,8);
if ($postfinger =~ /\-o/) {
print "<tr><td class='e'></td><td class='v'></td>",
@@ -136,7 +140,7 @@ if ($Master eq 1 ) {
if ( !grep(/^#|^\[ \]*$/,$postfinger));
}
}
close(MAILQ);
close($mailq);
print "</table><br>";
}
@@ -144,74 +148,74 @@ if ($Permissions eq 1 ) {
print '<h1 align="center">Specific file and directory permissions</h1><br>';
print '<table border="0" cellpadding="0" width="600" align="center">';
print "<tr><td class='e'><b>Permission</b> Deep <b>Owner</b> <b>Group</b> Size Date <b>Directory/File</b></td></tr>";
open(MAILQ, "/bin/ls -ld `$config{'postfix_config_command'} -h queue_directory`/maildrop 2>/dev/null |");
while (my $postfinger = <MAILQ>) {
open($mailq, "-|", "/bin/ls -ld `$config{'postfix_config_command'} -h queue_directory`/maildrop 2>/dev/null");
while (my $postfinger = <$mailq>) {
print "<tr><td class='v'>$postfinger</td></tr>"
if ( !grep(/total|^#|^\[ \]*$/,$postfinger));
}
close(MAILQ);
close($mailq);
print "<tr><td></td></tr>";
open(MAILQ, "/bin/ls -ld `$config{'postfix_config_command'} -h queue_directory`/public 2>/dev/null |");
while (my $postfinger = <MAILQ>) {
open($mailq, "-|", "/bin/ls -ld `$config{'postfix_config_command'} -h queue_directory`/public 2>/dev/null");
while (my $postfinger = <$mailq>) {
print "<tr><td class='v'>$postfinger</td></tr>"
if ( !grep(/total|^#|^\[ \]*$/,$postfinger));
}
close(MAILQ);
close($mailq);
print "<tr><td></td></tr>";
if (! open(MAILQ, "/bin/ls -l `$config{'postfix_config_command'} -h queue_directory`/public 2>/dev/null |")) {
if (! open($mailq, "-|", "/bin/ls -l `$config{'postfix_config_command'} -h queue_directory`/public 2>/dev/null")) {
print '<center><b>WARNING: No access to $queue_directory/public<br>Try running postfinger as user root or postfix</b></center><br>';
} else {
while (my $postfinger = <MAILQ>) {
while (my $postfinger = <$mailq>) {
print "<tr><td class='v'>$postfinger</td></tr>"
if ( !grep(/total|^#|^\[ \]*$/,$postfinger));
}
close(MAILQ);
close($mailq);
print "<tr><td></td></tr>";
}
open(MAILQ, "/bin/ls -ld `$config{'postfix_config_command'} -h queue_directory`/private 2>/dev/null |");
while (my $postfinger = <MAILQ>) {
open($mailq, "-|", "/bin/ls -ld `$config{'postfix_config_command'} -h queue_directory`/private 2>/dev/null");
while (my $postfinger = <$mailq>) {
print "<tr><td class='v'>$postfinger</td></tr>"
if ( !grep(/total|^#|^\[ \]*$/,$postfinger));
}
close(MAILQ);
close($mailq);
print "<tr><td></td></tr>";
if (! open(MAILQ, "/bin/ls -l `$config{'postfix_config_command'} -h queue_directory`/private 2>/dev/null |")) {
if (! open($mailq, "-|", "/bin/ls -l `$config{'postfix_config_command'} -h queue_directory`/private 2>/dev/null")) {
print '<center><b>WARNING: No access to $queue_directory/private<br>Try running postfinger as user root or postfix</b></center><br>';
} else {
while (my $postfinger = <MAILQ>) {
while (my $postfinger = <$mailq>) {
print "<tr><td class='v'>$postfinger</td></tr>"
if ( !grep(/total|^#|^\[ \]*$/,$postfinger));
}
close(MAILQ);
close($mailq);
print "<tr><td></td></tr>";
}
open(MAILQ, "/bin/ls -l `$config{'postfix_config_command'} -h command_directory`/postdrop 2>/dev/null |");
while (my $postfinger = <MAILQ>) {
open($mailq, "-|", "/bin/ls -l `$config{'postfix_config_command'} -h command_directory`/postdrop 2>/dev/null");
while (my $postfinger = <$mailq>) {
print "<tr><td class='v'>$postfinger</td></tr>"
if ( !grep(/total|^#|^\[ \]*$/,$postfinger));
}
close(MAILQ);
close($mailq);
print "<tr><td></td></tr>";
open(MAILQ, "/bin/ls -l `$config{'postfix_config_command'} -h command_directory`/postqueue 2>/dev/null |");
while (my $postfinger = <MAILQ>) {
open($mailq, "-|", "/bin/ls -l `$config{'postfix_config_command'} -h command_directory`/postqueue 2>/dev/null");
while (my $postfinger = <$mailq>) {
print "<tr><td class='v'>$postfinger</td></tr>"
if ( !grep(/total|^#|^\[ \]*$/,$postfinger));
}
close(MAILQ);
close($mailq);
print "</table><br>";
}
if ($Libraries eq 1 ) {
print '<h1 align="center">Library dependencies</h1>';
print '<table border="0" cellpadding="0" width="600" align="center">';
if (! open(MAILQ, "/usr/bin/ldd `$config{'postfix_config_command'} -h daemon_directory`/smtpd 2>/dev/null |")) {
if (! open($mailq, "-|", "/usr/bin/ldd `$config{'postfix_config_command'} -h daemon_directory`/smtpd 2>/dev/null")) {
print '<center><b>WARNING: Can not find ldd. Check you have it installed and in your path</b></center><br>';
} else {
while (my $postfinger = <MAILQ>) {
while (my $postfinger = <$mailq>) {
($postf1,$postf2)=split(/=/,$postfinger,2);
print "<tr><td class='e'><b>$postf1</b></td>";
print "<td class='v'>=$postf2</td></tr>";
}
close(MAILQ);
close($mailq);
print "</table><br>";
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,4 +1,7 @@
require 'postfix-lib.pl';
require 'postfix-lib.pl'; ## no critic
use strict;
use warnings;
our ($version_file);
sub module_install
{

View File

@@ -7,7 +7,10 @@
#
# << Here are all options seen in Postfix sample-rate.cf >>
require './postfix-lib.pl';
require './postfix-lib.pl'; ## no critic
use strict;
use warnings;
our ($default, $no_, $none, %access, %text);
$access{'rate'} || &error($text{'rate_ecannot'});

View File

@@ -1,7 +1,10 @@
#!/usr/local/bin/perl
# Have Postfix re-read its config
require './postfix-lib.pl';
require './postfix-lib.pl'; ## no critic
use strict;
use warnings;
our ($err, %access, %text);
$access{'startstop'} || &error($text{'reload_ecannot'});
&error_setup($text{'reload_efailed'});

View File

@@ -8,7 +8,10 @@
# << Here are all options seen in Postfix sample-relocated.cf >>
require './postfix-lib.pl';
require './postfix-lib.pl'; ## no critic
use strict;
use warnings;
our (%access, %text);
&ReadParse();
$access{'relocated'} || &error($text{'relocated_ecannot'});

View File

@@ -7,7 +7,10 @@
#
# << Here are all options seen in Postfix sample-resource.cf >>
require './postfix-lib.pl';
require './postfix-lib.pl'; ## no critic
use strict;
use warnings;
our ($default, $no_, $none, %access, %text);
$access{'resource'} || &error($text{'resource_ecannot'});

View File

@@ -1,7 +1,10 @@
#!/usr/local/bin/perl
# Show SMTP authentication related parameters
require './postfix-lib.pl';
require './postfix-lib.pl'; ## no critic
use strict;
use warnings;
our ($default, $level, $no_, $none, $pmap, $postfix_version, $rh, $rpass, $ruser, %access, @cbs, %opts, %recip, %relay, %text);
$access{'sasl'} || &error($text{'sasl_ecannot'});
&ui_print_header(undef, $text{'sasl_title'}, "");
@@ -23,7 +26,7 @@ print &ui_table_start($text{'sasl_title'}, "width=100%", 2);
%opts = map { $_, 1 }
split(/[\s,]+/, &get_current_value("smtpd_sasl_security_options"));
@cbs = ( );
foreach $o ("noanonymous", "noplaintext", "noactive", "nodictionary", "forward_secrecy") {
foreach my $o ("noanonymous", "noplaintext", "noactive", "nodictionary", "forward_secrecy") {
push(@cbs, &ui_checkbox("sasl_opts", $o, $text{'sasl_'.$o}, $opts{$o}));
}
print &ui_table_row($text{'sasl_opts'}, join("<br>\n", @cbs), 3);
@@ -32,7 +35,7 @@ print &ui_table_row($text{'sasl_opts'}, join("<br>\n", @cbs), 3);
%recip = map { $_, 1 }
split(/[\s,]+/, &get_current_value("smtpd_recipient_restrictions"));
@cbs = ( );
foreach $o (&list_smtpd_restrictions()) {
foreach my $o (&list_smtpd_restrictions()) {
push(@cbs, &ui_checkbox("sasl_recip", $o, $text{'sasl_'.$o},
$recip{$o}));
}
@@ -42,7 +45,7 @@ print &ui_table_row($text{'sasl_recip'}, join("<br>\n", @cbs), 3);
%relay = map { $_, 1 }
split(/[\s,]+/, &get_current_value("smtpd_relay_restrictions"));
@cbs = ( );
foreach $o (&list_smtpd_restrictions()) {
foreach my $o (&list_smtpd_restrictions()) {
push(@cbs, &ui_checkbox("sasl_relay", $o, $text{'sasl_'.$o},
$relay{$o}));
}

View File

@@ -6,7 +6,10 @@
# Save, modify, delete an alias for Postfix
require './postfix-lib.pl';
require './postfix-lib.pl'; ## no critic
use strict;
use warnings;
our ($err, $i, $loga, $module_config_directory, $t, $v, %access, @afiles, @aliases, %in, %newa, %text, @values);
&ReadParse();
$access{'aliases'} || &error($text{'aliases_ecannot'});
@@ -15,21 +18,22 @@ $access{'aliases'} || &error($text{'aliases_ecannot'});
# Get the alias (if editing or deleting)
@afiles = &get_aliases_files(&get_current_value("alias_maps"));
@aliases = &list_postfix_aliases();
my $alias;
if (!$in{'new'}) {
$a = $aliases[$in{'num'}];
$alias = $aliases[$in{'num'}];
}
&lock_alias_files(\@afiles);
if ($in{'delete'}) {
# delete some alias
&delete_postfix_alias($a);
$loga = $a;
&delete_postfix_alias($alias);
$loga = $alias;
}
else {
# saving or creating .. check inputs
$in{'name'} =~ /^[^:@ ]+$/ ||
&error(&text('asave_eaddr', $in{'name'}));
if ($in{'new'} || uc($a->{'name'}) ne uc($in{'name'})) {
if ($in{'new'} || uc($alias->{'name'}) ne uc($in{'name'})) {
# is this name taken?
for($i=0; $i<@aliases; $i++) {
if (uc($in{'name'}) eq uc($aliases[$i]->{'name'})) {
@@ -86,7 +90,7 @@ else {
&create_postfix_alias(\%newa);
}
else {
&modify_postfix_alias($a, \%newa);
&modify_postfix_alias($alias, \%newa);
}
$loga = \%newa;
}

View File

@@ -1,7 +1,10 @@
#!/usr/local/bin/perl
# Save SMTP authentication options
require './postfix-lib.pl';
require './postfix-lib.pl'; ## no critic
use strict;
use warnings;
our ($err, %access, %in, %newopts, %oldopts, @opts, %text, @v);
&ReadParse();
@@ -23,7 +26,7 @@ else {
%newopts = map { $_, 1 } split(/\0/, $in{'client'});
# Save boolean options
foreach $o (&list_client_restrictions()) {
foreach my $o (&list_client_restrictions()) {
if ($newopts{$o} && !$oldopts{$o}) {
push(@opts, $o);
}
@@ -33,9 +36,9 @@ else {
}
# Save options with values
foreach $o (&list_multi_client_restrictions()) {
foreach my $o (&list_multi_client_restrictions()) {
# Find all current positions
local @pos;
my @pos;
for(my $i=0; $i<@opts; $i++) {
push(@pos, $i) if ($opts[$i] eq $o);
}

View File

@@ -1,7 +1,10 @@
#!/usr/local/bin/perl
# Update a manually edited map file
require './postfix-lib.pl';
require './postfix-lib.pl'; ## no critic
use strict;
use warnings;
our ($err, %access, @files, %in, %text);
&ReadParseMime();
&error_setup($text{'manual_err'});
$access{'manual'} || &error($text{'manual_ecannot'});
@@ -10,9 +13,10 @@ $access{'manual'} || &error($text{'manual_ecannot'});
# Save the data
$in{'data'} =~ s/\r//g;
&open_lock_tempfile(FILE, ">$in{'file'}");
&print_tempfile(FILE, $in{'data'});
&close_tempfile(FILE);
my $filefh = "FILE";
&open_lock_tempfile($filefh, ">$in{'file'}");
&print_tempfile($filefh, $in{'data'});
&close_tempfile($filefh);
# Regenerate map
&regenerate_map_table($in{'map_name'});

View File

@@ -6,7 +6,10 @@
# Save, modify, delete a map for Postfix
require './postfix-lib.pl';
require './postfix-lib.pl'; ## no critic
use strict;
use warnings;
our ($action, $err, $logmap, $nfunc, $vfunc, $whatfailed, %access, %in, %text);
&ReadParse();
@@ -21,7 +24,7 @@ my $add = 1; my %map;
## added to split main_parameter:sub_parameter
my ($mainparm,$subparm)=split /:/,$in{'map_name'};
foreach $trans (@{$maps})
foreach my $trans (@{$maps})
{
if ($trans->{'number'} == $in{'num'}) { $add = 0; %map = %{$trans}; }
}
@@ -75,7 +78,7 @@ if ($in{'delete'})
elsif ($add == 0)
{
# modify an existing map
local %newmap = ( 'name' => $in{'name'},
my %newmap = ( 'name' => $in{'name'},
'value' => $in{'value'},
'cmt' => $in{'cmt'} );
&modify_mapping($in{'map_name'}, \%map, \%newmap);
@@ -85,7 +88,7 @@ elsif ($add == 0)
else
{
# add a new map -- much more easy! :-)
local %newmap = ( 'name' => $in{'name'},
my %newmap = ( 'name' => $in{'name'},
'value' => $in{'value'},
'cmt' => $in{'cmt'} );
&create_mapping($in{'map_name'}, \%newmap);

View File

@@ -1,7 +1,10 @@
#!/usr/local/bin/perl
# Create, update or delete a server process
require './postfix-lib.pl';
require './postfix-lib.pl'; ## no critic
use strict;
use warnings;
our ($clash, $err, $master, $prog, %access, %config, %in, %text);
$access{'master'} || &error($text{'master_ecannot'});
&ReadParse();
&error_setup($text{'master_err'});

View File

@@ -6,7 +6,10 @@
# Save Postfix options
require './postfix-lib.pl';
require './postfix-lib.pl'; ## no critic
use strict;
use warnings;
our ($err, %access, %in, %text);
&ReadParse();

View File

@@ -6,7 +6,10 @@
# Save Postfix options ; special because for aliases
require './postfix-lib.pl';
require './postfix-lib.pl'; ## no critic
use strict;
use warnings;
our ($err, %in, %text);
&ReadParse();

View File

@@ -1,6 +1,9 @@
#!/usr/local/bin/perl
require './postfix-lib.pl';
require './postfix-lib.pl'; ## no critic
use strict;
use warnings;
our ($err, %access, %in, %text);
&ReadParse();

View File

@@ -6,7 +6,10 @@
# Save Postfix options ; special because for virtual tables
require './postfix-lib.pl';
require './postfix-lib.pl'; ## no critic
use strict;
use warnings;
our ($err, %access, %in, %text);
&ReadParse();

View File

@@ -6,7 +6,10 @@
# Save Postfix options ; special because for canonical tables
require './postfix-lib.pl';
require './postfix-lib.pl'; ## no critic
use strict;
use warnings;
our ($err, %access, %in, %text);
&ReadParse();

View File

@@ -6,7 +6,10 @@
# Save Postfix options ; special because for sender transport maps
require './postfix-lib.pl';
require './postfix-lib.pl'; ## no critic
use strict;
use warnings;
our ($err, %access, %in, %text);
&ReadParse();

View File

@@ -6,7 +6,10 @@
# Save Postfix options ; special because for virtual tables
require './postfix-lib.pl';
require './postfix-lib.pl'; ## no critic
use strict;
use warnings;
our ($err, %access, %in, %text);
&ReadParse();

View File

@@ -6,7 +6,10 @@
# Save Postfix options ; special case in which we need to regenerate the relocated table
require './postfix-lib.pl';
require './postfix-lib.pl'; ## no critic
use strict;
use warnings;
our ($err, %in, %text);
&ReadParse();

View File

@@ -6,7 +6,10 @@
# Save Postfix options ; special because for relocated tables
require './postfix-lib.pl';
require './postfix-lib.pl'; ## no critic
use strict;
use warnings;
our ($err, %access, %in, %text);
&ReadParse();

View File

@@ -6,7 +6,10 @@
# Save Postfix options ; special because for sni tables
require './postfix-lib.pl';
require './postfix-lib.pl'; ## no critic
use strict;
use warnings;
our ($err, %access, %in, %text);
&ReadParse();

View File

@@ -6,7 +6,10 @@
# Save Postfix options ; special because for transport tables
require './postfix-lib.pl';
require './postfix-lib.pl'; ## no critic
use strict;
use warnings;
our ($err, %access, %in, %text);
&ReadParse();

View File

@@ -6,7 +6,10 @@
# Save Postfix options ; special because for virtual tables
require './postfix-lib.pl';
require './postfix-lib.pl'; ## no critic
use strict;
use warnings;
our ($err, $virtual_maps, %access, %in, %text);
&ReadParse();

View File

@@ -1,7 +1,10 @@
#!/usr/local/bin/perl
# Save SMTP authentication options
require './postfix-lib.pl';
require './postfix-lib.pl'; ## no critic
use strict;
use warnings;
our ($err, $newmap, $old, $pmap, $postfix_version, $rh, %access, %in, %newrecip, %newrelay, @opts, @recip, @relay, %text);
&ReadParse();
@@ -36,7 +39,7 @@ if (!$in{'login_none'}) {
# Save recipient options that we care about
@recip = split(/[\s,]+/, &get_current_value("smtpd_recipient_restrictions"));
%newrecip = map { $_, 1 } split(/\0/, $in{'sasl_recip'});
foreach $o (&list_smtpd_restrictions()) {
foreach my $o (&list_smtpd_restrictions()) {
if ($newrecip{$o}) {
push(@recip, $o) if (&indexof($o, @recip) < 0);
}
@@ -49,7 +52,7 @@ foreach $o (&list_smtpd_restrictions()) {
# Save relay options that we care about
@relay = split(/[\s,]+/, &get_current_value("smtpd_relay_restrictions"));
%newrelay = map { $_, 1 } split(/\0/, $in{'sasl_relay'});
foreach $o (&list_smtpd_restrictions()) {
foreach my $o (&list_smtpd_restrictions()) {
if ($newrelay{$o}) {
push(@relay, $o) if (&indexof($o, @relay) < 0);
}

View File

@@ -7,7 +7,10 @@
#
# << Here are all options seen in Postfix sample-smtp.cf >>
require './postfix-lib.pl';
require './postfix-lib.pl'; ## no critic
use strict;
use warnings;
our ($default, $inet, $level, $no_, $none, $postfix_version, $pref, %access, %inet, @opts, %text);
$access{'smtp'} || &error($text{'smtp_ecannot'});

View File

@@ -8,7 +8,10 @@
#
# << Here are all options seen in Postfix sample-smtpd.cf >>
require './postfix-lib.pl';
require './postfix-lib.pl'; ## no critic
use strict;
use warnings;
our ($default, $no_, $none, %access, %text);
&ReadParse();
$access{'smtpd'} || &error($text{'smtpd_ecannot'});

View File

@@ -8,7 +8,10 @@
# << Here are all options seen in Postfix sample-sni.cf >>
require './postfix-lib.pl';
require './postfix-lib.pl'; ## no critic
use strict;
use warnings;
our (%access, %text);
&ReadParse();
$access{'sni'} || &error($text{'sni_ecannot'});

View File

@@ -5,7 +5,10 @@
#
# Start postfix
require './postfix-lib.pl';
require './postfix-lib.pl'; ## no critic
use strict;
use warnings;
our ($err, %access, %text);
$access{'startstop'} || &error($text{'start_ecannot'});
&error_setup($text{'start_efailed'});

View File

@@ -5,7 +5,10 @@
#
# Stop postfix
require './postfix-lib.pl';
require './postfix-lib.pl'; ## no critic
use strict;
use warnings;
our ($err, %access, %text);
$access{'startstop'} || &error($text{'stop_ecannot'});
&error_setup($text{'stop_efailed'});

72
postfix/t/perlcritic.t Normal file
View File

@@ -0,0 +1,72 @@
#!/usr/bin/perl
use strict;
use warnings;
use Test::More;
BEGIN {
eval { require Perl::Critic; 1 }
or plan skip_all => 'Perl::Critic not installed';
}
use File::Find;
sub script_dir
{
my $path = $0;
if ($path =~ m{^/}) {
$path =~ s{/[^/]+$}{};
return $path;
}
my $cwd = `pwd`;
chomp($cwd);
if ($path =~ m{/}) {
$path =~ s{/[^/]+$}{};
return $cwd.'/'.$path;
}
return $cwd;
}
my $bindir = script_dir();
my $module_dir = "$bindir/..";
chdir($module_dir) or die "chdir: $!";
my @files;
find(
sub {
# Skip symlinks: several postfix files (aliases-lib.pl, autoreply.pl,
# filter.pl, edit_*file.cgi, save_*file.cgi, boxes-lib.pl) are symlinks
# into the sendmail and mailboxes modules. Those belong to other
# modules and are linted by their own test suites.
return if -l;
return if -d;
return unless /\.(pl|cgi)\z/;
# ".pl" is also the Polish translation suffix in Webmin. Skip
# "<file>.pl" when a sibling "<file>" (no extension) exists, so
# data files like config.info.pl and module.info.pl are not linted
# as Perl. (Same heuristic as the repo-root compile.t.)
if (/^(.*)\.pl\z/ && -e $1) {
return;
}
push(@files, $File::Find::name);
},
'.'
);
@files = sort @files;
if (!@files) {
plan skip_all => 'no perl files to check';
}
my $critic = Perl::Critic->new(
-profile => "$bindir/../../.perlcriticrc",
);
foreach my $file (@files) {
my @violations = $critic->critique($file);
is(scalar @violations, 0, "$file perlcritic");
if (@violations) {
diag join("", @violations);
}
}
done_testing();

249
postfix/t/run-tests.t Normal file
View File

@@ -0,0 +1,249 @@
#!/usr/bin/perl
use strict;
use warnings;
use Test::More;
use Cwd qw(abs_path);
use File::Temp qw(tempdir);
sub script_dir
{
my $path = $0;
if ($path =~ m{^/}) {
$path =~ s{/[^/]+$}{};
return $path;
}
my $cwd = `pwd`;
chomp($cwd);
if ($path =~ m{/}) {
$path =~ s{/[^/]+$}{};
return $cwd.'/'.$path;
}
return $cwd;
}
my $bindir = script_dir();
my $rootdir = abs_path("$bindir/../..") or die "rootdir: $!";
my $confdir = tempdir(CLEANUP => 1);
my $vardir = tempdir(CLEANUP => 1);
# Global Webmin config
open(my $cfh, ">", "$confdir/config") or die "config: $!";
print $cfh "os_type=linux\nos_version=0\n";
close($cfh);
open(my $vfh, ">", "$confdir/var-path") or die "var-path: $!";
print $vfh "$vardir\n";
close($vfh);
# A main.cf to drive the config parser
my $maincf = "$confdir/main.cf";
my $mastercf = "$confdir/master.cf";
open(my $mc, ">", $maincf) or die "main.cf: $!";
print $mc <<'EOF';
myhostname = mail.example.com
mydestination = example.com,
mail.example.com,
localhost
compatibility_level = 2
util_lt = {{$compatibility_level} < {3} ? {old} : {new}}
util_ge = {{$compatibility_level} >= {3} ? {high} : {low}}
util_eq = {{$compatibility_level} == {2} ? {match} : {nomatch}}
subtest = key1 valueA key2 valueB
alias_maps = hash:/etc/postfix/aliases, hash:/etc/aliases
EOF
close($mc);
# A master.cf with one enabled and one disabled service, plus a continuation
open(my $ms, ">", $mastercf) or die "master.cf: $!";
print $ms <<'EOF';
smtp inet n - y - - smtpd
#qmgr unix n - n 300 1 qmgr
pickup unix n - y 60 1 pickup
-o content_filter=foo
EOF
close($ms);
# Per-module config
mkdir "$confdir/postfix" or die "postfix confdir: $!";
open(my $mod, ">", "$confdir/postfix/config") or die "module config: $!";
print $mod "postfix_config_file=$maincf\n";
print $mod "postfix_master=$mastercf\n";
print $mod "postfix_config_command=/bin/true\n";
print $mod "postfix_control_command=/bin/true\n";
print $mod "prefix_cmts=0\n";
close($mod);
# Pre-seed the version file so loading the lib does not shell out to postconf.
open(my $ver, ">", "$confdir/postfix/version") or die "version: $!";
print $ver "3.4.0\n";
close($ver);
$ENV{'WEBMIN_CONFIG'} = $confdir;
$ENV{'WEBMIN_VAR'} = $vardir;
$ENV{'FOREIGN_MODULE_NAME'} = 'postfix';
$ENV{'FOREIGN_ROOT_DIRECTORY'} = $rootdir;
chdir("$bindir/..") or die "chdir: $!";
require "$bindir/../postfix-lib.pl";
our (%config, $postfix_version, $virtual_maps, $ldap_timeout, $config_dir);
# --- load-time globals -----------------------------------------------------
is($postfix_version, '3.4.0', 'postfix_version read from version file');
is($virtual_maps, 'virtual_alias_maps', 'virtual_maps for >= 2.x');
is($ldap_timeout, 'ldap_timeout', 'ldap_timeout for >= 2.x');
is($config_dir, $confdir, 'guess_config_dir is dirname of main.cf');
# --- file_map_type ---------------------------------------------------------
ok(file_map_type('hash'), 'hash is a file map type');
ok(file_map_type('pcre'), 'pcre is a file map type');
ok(file_map_type('cidr'), 'cidr is a file map type');
ok(!file_map_type('mysql'),'mysql is not a file map type');
ok(!file_map_type('ldap'), 'ldap is not a file map type');
# --- get_maps_types_files --------------------------------------------------
is_deeply([ get_maps_types_files('hash:/etc/postfix/canonical') ],
[ [ 'hash', '/etc/postfix/canonical' ] ],
'single type:file parsed');
is_deeply([ get_maps_types_files(
'hash:/etc/postfix/canonical, proxy:pcre:/etc/postfix/x') ],
[ [ 'hash', '/etc/postfix/canonical' ],
[ 'pcre', '/etc/postfix/x' ] ],
'multiple maps and proxy: prefix parsed');
is_deeply([ get_maps_types_files('mysql:/etc/postfix/m.cf') ],
[ [ 'mysql', '/etc/postfix/m.cf' ] ],
'mysql backend type:file parsed');
is_deeply([ get_maps_types_files('') ], [],
'empty value yields no maps');
is_deeply([ get_maps_types_files('garbage-without-colon') ], [],
'unparseable value yields no maps');
# --- get_maps_files (path extraction) --------------------------------------
is_deeply([ get_maps_files('hash:/etc/postfix/aliases,hash:/etc/aliases') ],
[ '/etc/postfix/aliases', '/etc/aliases' ],
'get_maps_files extracts both file paths');
is_deeply([ get_maps_files('static:foo') ], [],
'get_maps_files ignores non-path map values');
# --- get_current_value (main.cf parser) ------------------------------------
is(get_current_value('myhostname', 1), 'mail.example.com',
'single-line parameter parsed');
my $dest = get_current_value('mydestination', 1);
like($dest, qr/example\.com/, 'continuation line: first value present');
like($dest, qr/localhost/, 'continuation line: trailing value joined');
is(get_current_value('no_such_param', 1), undef,
'unknown parameter with nodef returns undef (no postconf fallback)');
is(get_current_value('subtest:key1', 1), 'valueA',
'sub-parameter extraction (foo:bar) returns value after the key');
# --- resolve_current_value (compatibility_level conditionals) --------------
# Exercises the operator-dispatch rewrite of the old stringy eval.
is(resolve_current_value('util_lt'), 'old',
'resolve "<": level 2 is < 3, takes true branch');
is(resolve_current_value('util_ge'), 'low',
'resolve ">=": level 2 is not >= 3, takes false branch');
is(resolve_current_value('util_eq'), 'match',
'resolve "==": level 2 == 2, takes true branch');
is(resolve_current_value('myhostname'), 'mail.example.com',
'resolve passes through a plain value unchanged');
# --- master.cf parser + serializer -----------------------------------------
my $master = get_master_config();
is(ref($master), 'ARRAY', 'get_master_config returns array ref');
is(scalar(@$master), 3, 'three service entries parsed');
my ($smtp) = grep { $_->{'name'} eq 'smtp' } @$master;
my ($qmgr) = grep { $_->{'name'} eq 'qmgr' } @$master;
my ($pickup) = grep { $_->{'name'} eq 'pickup' } @$master;
ok($smtp, 'smtp service parsed');
ok($smtp->{'enabled'}, 'smtp is enabled');
is($smtp->{'type'}, 'inet', 'smtp type');
is($smtp->{'chroot'}, 'y', 'smtp chroot column');
is($smtp->{'command'}, 'smtpd','smtp command');
ok($qmgr, 'commented service still parsed');
ok(!$qmgr->{'enabled'}, 'commented service is disabled');
ok($pickup, 'pickup service parsed');
is($pickup->{'command'}, 'pickup -o content_filter=foo',
'continuation line appended to command');
# master_line round-trips an entry back to its on-disk form
is(master_line($smtp),
"smtp\tinet\tn\t-\ty\t-\t-\tsmtpd",
'master_line serializes an enabled service with tabs');
is(master_line($qmgr),
"#qmgr\tunix\tn\t-\tn\t300\t1\tqmgr",
'master_line prefixes a disabled service with #');
# --- is_table_comment / make_table_comment ---------------------------------
{
local $config{'prefix_cmts'} = 0;
is(is_table_comment('# hello world'), 'hello world',
'plain comment text extracted when prefix_cmts off');
is_deeply([ make_table_comment('a note') ], [ '# a note' ],
'make_table_comment emits a plain # line');
is_deeply([ make_table_comment('') ], [],
'make_table_comment emits nothing for empty comment');
}
{
local $config{'prefix_cmts'} = 1;
is(is_table_comment('# Webmin: tagged'), 'tagged',
'Webmin-tagged comment extracted when prefix_cmts on');
is(is_table_comment('# untagged'), undef,
'untagged comment ignored when prefix_cmts on');
is_deeply([ make_table_comment('z') ], [ '# Webmin: z' ],
'make_table_comment emits a Webmin-tagged line when prefix_cmts on');
}
# --- in_props --------------------------------------------------------------
is(in_props([ qw(cn foo objectClass top) ], 'objectClass'), 'top',
'in_props returns value following a matched name');
is(in_props([ qw(cn foo) ], 'mail'), undef,
'in_props returns undef for an absent name');
is(in_props([ qw(CN foo) ], 'cn'), 'foo',
'in_props matches case-insensitively');
# --- get_ldap_key ----------------------------------------------------------
is_deeply([ get_ldap_key({}) ],
[ 'mailacceptinggeneralid', '(mailacceptinggeneralid=*)' ],
'get_ldap_key default attribute and filter');
is_deeply([ get_ldap_key({ 'query_filter' => 'mail=%s' }) ],
[ 'mail', '(mail=*)' ],
'get_ldap_key derives attribute and filter from query_filter');
# --- make_map_ldap_dn ------------------------------------------------------
{
local $config{'ldap_doms'} = 1; # allow sub-domain DNs
local $config{'ldap_id'} = undef; # default to cn
my $conf = { 'search_base' => 'dc=example,dc=com', 'scope' => 'sub' };
is(make_map_ldap_dn({ 'name' => 'user@dom.com' }, $conf),
'cn=user,cn=dom.com,dc=example,dc=com',
'make_map_ldap_dn builds a per-user DN inside a domain');
is(make_map_ldap_dn({ 'name' => '@dom.com' }, $conf),
'cn=default,cn=dom.com,dc=example,dc=com',
'make_map_ldap_dn builds a catch-all DN for a domain');
is(make_map_ldap_dn({ 'name' => 'literal' }, $conf),
'cn=literal,dc=example,dc=com',
'make_map_ldap_dn builds a flat DN for a non-address name');
}
# --- get_backend_config ----------------------------------------------------
my $backend = "$confdir/mysql.cf";
open(my $bfh, ">", $backend) or die "backend: $!";
print $bfh "user = postfix\npassword = secret\n# a comment\nhosts = localhost\n";
close($bfh);
my $bc = get_backend_config($backend);
is($bc->{'user'}, 'postfix', 'backend config user parsed');
is($bc->{'password'}, 'secret', 'backend config password parsed');
is($bc->{'hosts'}, 'localhost', 'backend config hosts parsed');
# --- list_smtpd_restrictions (version-dependent constant) ------------------
my @restr = list_smtpd_restrictions();
ok((grep { $_ eq 'permit_mynetworks' } @restr),
'smtpd restrictions include permit_mynetworks');
ok((grep { $_ eq 'reject_unknown_reverse_client_hostname' } @restr),
'>= 2.3 uses reject_unknown_reverse_client_hostname');
done_testing();

View File

@@ -8,7 +8,10 @@
# << Here are all options seen in Postfix sample-transport.cf >>
require './postfix-lib.pl';
require './postfix-lib.pl'; ## no critic
use strict;
use warnings;
our (%access, %text);
&ReadParse();
$access{'transport'} || &error($text{'transport_ecannot'});

View File

@@ -2,8 +2,11 @@
# view_mailq.cgi
# Display some message from the mail queue
require './postfix-lib.pl';
require './boxes-lib.pl';
require './postfix-lib.pl'; ## no critic
use strict;
use warnings;
our ($body, $bodyhtml, $desc, $mail, $rlink, $subs, %access, @attach, %config, %in, @sub, %text);
require './boxes-lib.pl'; ## no critic
&ReadParse();
$access{'mailq'} || &error($text{'mailq_ecannot'});
@@ -12,9 +15,9 @@ $mail || &error($text{'mailq_egone'});
&parse_mail($mail);
@sub = split(/\0/, $in{'sub'});
$subs = join("", map { "&sub=$_" } @sub);
foreach $s (@sub) {
foreach my $s (@sub) {
# We are looking at a mail within a mail ..
local $amail = &extract_mail($mail->{'attach'}->[$s]->{'data'});
my $amail = &extract_mail($mail->{'attach'}->[$s]->{'data'});
&parse_mail($amail);
$mail = $amail;
}
@@ -49,7 +52,7 @@ if ($in{'headers'}) {
print &ui_table_row($text{'mail_rfc'},
&html_escape($mail->{'fromline'}));
}
foreach $h (@{$mail->{'headers'}}) {
foreach my $h (@{$mail->{'headers'}}) {
print &ui_table_row($h->[0],
&html_escape(&decode_mimewords($h->[1])), 1, [ "nowrap" ]);
}
@@ -84,7 +87,7 @@ print &ui_table_end();
# Find body attachment
@attach = @{$mail->{'attach'}};
foreach $a (@attach) {
foreach my $a (@attach) {
if ($a->{'type'} eq 'text/plain') {
$body = $a;
last;
@@ -93,7 +96,7 @@ foreach $a (@attach) {
if ($body) {
print &ui_table_start($text{'view_body'}, "width=100%", 2);
$bodyhtml = "";
foreach $l (&wrap_lines($body->{'data'}, $config{'wrap_width'})) {
foreach my $l (&wrap_lines($body->{'data'}, $config{'wrap_width'})) {
$bodyhtml .= &link_urls_and_escape($l)."\n";
}
print &ui_table_row(undef, "<pre>".$bodyhtml."</pre>", 2);
@@ -107,7 +110,7 @@ if (@attach) {
print &ui_columns_start([ $text{'view_afile'}, $text{'view_atype'},
$text{'view_asize'} ], 100, 0);
my $attachment_id;
foreach $a (@attach) {
foreach my $a (@attach) {
$attachment_id++;
if ($a->{'type'} eq 'message/rfc822') {
print &ui_columns_row([

View File

@@ -8,7 +8,10 @@
# << Here are all options seen in Postfix sample-virtual.cf >>
require './postfix-lib.pl';
require './postfix-lib.pl'; ## no critic
use strict;
use warnings;
our ($postfix_version, $virtual_maps, %access, %text);
&ReadParse();
$access{'virtual'} || &error($text{'virtual_ecannot'});