---- Changes since 1.390 ----
Added a Module Config option to support ~/Maildir mailboxes (even though Sendmail doesn't support this natively).
Added an option to show the directory queued messages are in, which is useful on systems with several queues.
+Network ports and addresses used by Sendmail can now be more easily edited on the new Network Ports page, which updates both sendmail.cf and any .mc file.
print "<tr> <td><b>$text{'acl_flushq'}</b></td> <td>\n";
printf "<input type=radio name=flushq value=1 %s> $text{'yes'}\n",
$_[0]->{'flushq'} ? "checked" : "";
-printf "<input type=radio name=flushq value=0 %s> $text{'no'}</td> </tr>\n",
+printf "<input type=radio name=flushq value=0 %s> $text{'no'}</td>\n",
$_[0]->{'flushq'} ? "" : "checked";
+print "<td><b>$text{'acl_ports'}</b></td> <td>\n";
+printf "<input type=radio name=ports value=1 %s> $text{'yes'}\n",
+ $_[0]->{'ports'} ? "checked" : "";
+printf "<input type=radio name=ports value=0 %s> $text{'no'}</td>\n",
+ $_[0]->{'ports'} ? "" : "checked";
+
# Virtusers
print "<tr> <td colspan=4><hr></td> </tr>\n";
sub acl_security_save
{
$_[0]->{'opts'} = $in{'opts'};
+$_[0]->{'ports'} = $in{'ports'};
$_[0]->{'cws'} = $in{'cws'};
$_[0]->{'masq'} = $in{'masq'};
$_[0]->{'trusts'} = $in{'trusts'};
qdomsmode=2
flushq=1
smode=1
+ports=1
$mcount = scalar(@qfiles);
}
-@olinks = ( "list_opts.cgi", "list_aliases.cgi", "list_cws.cgi", "list_masq.cgi", "list_trusts.cgi", "list_virtusers.cgi", "list_mailers.cgi", "list_generics.cgi", "list_cgs.cgi", "list_domains.cgi", "list_access.cgi", "list_relay.cgi", "list_features.cgi", "list_mailq.cgi", "../mailboxes/" );
+@olinks = ( "list_opts.cgi", "list_ports.cgi", "list_aliases.cgi", "list_cws.cgi", "list_masq.cgi", "list_trusts.cgi", "list_virtusers.cgi", "list_mailers.cgi", "list_generics.cgi", "list_cgs.cgi", "list_domains.cgi", "list_access.cgi", "list_relay.cgi", "list_features.cgi", "list_mailq.cgi", "../mailboxes/" );
-@otitles = ( "$text{'opts_title'} (O)", "$text{'aliases_title'} (aliases)", "$text{'cws_title'} (Cw)", "$text{'masq_title'} (CM)", "$text{'trusts_title'} (T)", "$text{'virtusers_title'} (virtuser)", "$text{'mailers_title'} (mailertable)", "$text{'generics_title'} (generics)", "$text{'cgs_title'} (CG)", "$text{'domains_title'} (domaintable)", "$text{'access_title'} (access)", "$text{'relay_title'} (CR)", $text{'features_title'}, "$text{'mailq_title'} (mailq)".(defined($mcount) ? "<br>".&text('mailq_count', $mcount) : ""), "$text{'boxes_title'}");
+@otitles = ( "$text{'opts_title'} (O)", $text{'ports_title'}, "$text{'aliases_title'} (aliases)", "$text{'cws_title'} (Cw)", "$text{'masq_title'} (CM)", "$text{'trusts_title'} (T)", "$text{'virtusers_title'} (virtuser)", "$text{'mailers_title'} (mailertable)", "$text{'generics_title'} (generics)", "$text{'cgs_title'} (CG)", "$text{'domains_title'} (domaintable)", "$text{'access_title'} (access)", "$text{'relay_title'} (CR)", $text{'features_title'}, "$text{'mailq_title'} (mailq)".(defined($mcount) ? "<br>".&text('mailq_count', $mcount) : ""), "$text{'boxes_title'}");
-@oicons = ( "images/opts.gif", "images/aliases.gif", "images/cws.gif", "images/masq.gif", "images/trusts.gif", "images/virtusers.gif", "images/mailers.gif", "images/generics.gif", "images/cgs.gif", "images/domains.gif", "images/access.gif", "images/relay.gif", "images/features.gif", "images/mailq.gif", "images/boxes.gif" );
+@oicons = ( "images/opts.gif", "images/ports.gif", "images/aliases.gif", "images/cws.gif", "images/masq.gif", "images/trusts.gif", "images/virtusers.gif", "images/mailers.gif", "images/generics.gif", "images/cgs.gif", "images/domains.gif", "images/access.gif", "images/relay.gif", "images/features.gif", "images/mailq.gif", "images/boxes.gif" );
&filter_icons($access{'opts'}, "list_opts.cgi");
+&filter_icons($access{'ports'}, "list_ports.cgi");
&filter_icons($access{'cws'}, "list_cws.cgi");
&filter_icons($access{'masq'}, "list_masq.cgi");
&filter_icons($access{'trusts'}, "list_trusts.cgi");
file_err=Failed to edit file
acl_opts=Can edit sendmail options?
+acl_ports=Can edit network ports?
acl_cws=Can edit local domains?
acl_masq=Can configure domain masquerading?
acl_trusts=Can edit trusted users?
acl_spam=Spam control addresses this user can edit
log_opts=Changed sendmail options
+log_ports=Change network ports
log_alias_create=Created alias $1
log_alias_modify=Modified alias $1
log_alias_delete=Deleted alias $1
start_err=Failed to start sendmail
start_ecannot=You are not allowed to start sendmail
+
+ports_title=Network Ports
+ports_name=Port name
+ports_addr=Listen on address
+ports_all=All
+ports_ip=IP
+ports_port=Listen on port
+ports_opts=Port options
+ports_mod_a=Require SMTP authentication
+ports_mod_b=Use same interface for outgoing email
+ports_mod_c=Rerform hostname canonification
+ports_mod_f=Require fully qualified hostname
+ports_mod_h=Use name of interface for HELO
+ports_mod_C=Don't perform hostname canonification
+ports_mod_E=Disallow ETRN
+ports_def1=Accept email on port 25 and all addresses
+ports_def0=Accept email only on ports below ..
+ports_err=Failed to save network ports
+ports_ecannot=You are not allowed to manage network ports
+ports_ename=Invalid port name in row $1
+ports_eclash=Duplicate port name in row $1
+ports_eaddress=Missing or invalid IP address in row $1
+ports_eport=Missing or invalid port number in row $1
+
}
print "</td> </tr>\n";
-if ($ver >= 9) {
- print "<tr>\n";
- &options_input($text{'opts_daemon'}, "DaemonPortOptions", $conf,
- $default, 50);
- print "</tr>\n";
- }
-
print "<tr>\n";
&option_input($text{'opts_queuela'}, "QueueLA", $conf, $default, 6);
&option_input($text{'opts_refusela'}, "RefuseLA", $conf, $default,6);
--- /dev/null
+#!/usr/local/bin/perl
+# Show a list of TCP ports Sendmail uses
+
+require './sendmail-lib.pl';
+$access{'ports'} || &error($text{'ports_ecannot'});
+&ui_print_header(undef, $text{'ports_title'}, "");
+
+# Get and parse current setting
+$conf = &get_sendmailcf();
+foreach $dpo (&find_options("DaemonPortOptions", $conf)) {
+ local %opts;
+ foreach $o (split(/\s*,\s*/, $dpo->[1])) {
+ if ($o =~ /^([^=]+)=(\S+)$/) {
+ $opts{$1} = $2;
+ }
+ }
+ push(@ports, \%opts);
+ }
+
+# Show table of ports
+print &ui_form_start("save_ports.cgi");
+print &ui_radio("ports_def", @ports ? 0 : 1,
+ [ [ 1, $text{'ports_def1'} ], [ 0, $text{'ports_def0'} ] ])."<p>\n";
+print &ui_columns_start([
+ $text{'ports_name'},
+ $text{'ports_addr'},
+ $text{'ports_port'},
+ $text{'ports_opts'},
+ ], 100);
+$i = 0;
+@tds = ( "valign=top", "valign=top", "valign=top" );
+@known_opts = ( 'Name', 'Address', 'Port', 'Modifiers' );
+foreach $p (@ports, { }) {
+ @cols = ( );
+ foreach $k (@known_opts) {
+ $fk = substr($k, 0, 1);
+ if ($p->{$fk} && !$p->{$k}) {
+ # Using first letter abbreviation only
+ $p->{$k} = $p->{$fk};
+ delete($p->{$fk});
+ }
+ }
+ push(@cols, &ui_textbox("name_$i", $p->{'Name'}, 10));
+ push(@cols, &ui_opt_textbox("addr_$i", $p->{'Address'}, 15,
+ $text{'ports_all'}, $text{'ports_ip'}));
+ push(@cols, &ui_opt_textbox("port_$i", $p->{'Port'}, 6,
+ $text{'default'}." (25)"));
+ @mods = ( );
+ foreach $m (@port_modifier_flags) {
+ push(@mods, &ui_checkbox("mod_$i", $m, $text{'ports_mod_'.$m},
+ $p->{'Modifiers'} =~ /$m/));
+ }
+ push(@cols, &ui_grid_table(\@mods, 2));
+ print &ui_columns_row(\@cols, \@tds);
+
+ # Hidden field for other settings
+ foreach $k (@known_opts) {
+ delete($p->{$k});
+ }
+ print &ui_hidden("other_$i",
+ join(",", map { $_."=".$p->{$_} } keys %$p));
+ $i++;
+ }
+print &ui_columns_end();
+print &ui_form_end([ [ undef, $text{'save'} ] ]);
+
+&ui_print_footer("", $text{'index_return'});
+
&save_option("MaxRecipientsPerMessage", '\d+', $text{'opts_maxrcpt'});
&save_option("BadRcptThrottle", '\d+', $text{'opts_maxbad'});
}
-if ($ver >= 9) {
- &save_options("DaemonPortOptions", '.*\S.*', $text{'opts_daemon'});
- }
&flush_file_lines();
&unlock_file($config{'sendmail_cf'});
&restart_sendmail();
--- /dev/null
+#!/usr/local/bin/perl
+# Update the list of TCP ports Sendmail uses
+
+require './sendmail-lib.pl';
+require './features-lib.pl';
+
+&ReadParse();
+&error_setup($text{'ports_err'});
+$access{'ports'} || &error($text{'ports_ecannot'});
+
+# Parse and validate inputs
+@ports = ( );
+if (!$in{'ports_def'}) {
+ for($i=0; defined($name=$in{"name_$i"}); $i++) {
+ # Port name
+ next if (!$name);
+ $name =~ /^[a-z0-9\_]+$/i || &error(&text('ports_ename', $i+1));
+ $done{$name}++ && &error(&text('ports_eclash', $i+1));
+ @opts = ( "Name=$name" );
+
+ # IP address
+ if (!$in{"addr_${i}_def"}) {
+ &check_ipaddress($in{"addr_$i"}) ||
+ &error(&text('ports_eaddr', $i+1));
+ push(@opts, "Address=".$in{"addr_$i"});
+ }
+
+ # TCP port
+ if (!$in{"port_${i}_def"}) {
+ $in{"port_$i"} =~ /^\d+$/ && $in{"port_$i"} > 0 &&
+ $in{"port_$i"} < 65536 ||
+ &error(&text('ports_eport', $i+1));
+ push(@opts, "Port=".$in{"port_$i"});
+ }
+
+ # Modifiers
+ @mods = split(/\0/, $in{"mod_$i"});
+ if (@mods) {
+ push(@opts, "Modifiers=".join("", @mods));
+ }
+
+ # Other options
+ push(@opts, split(/,/, $in{"other_$i"}));
+ push(@ports, join(",", @opts));
+ }
+ }
+
+# Update sendmail.cf
+&lock_file($config{'sendmail_cf'});
+$conf = &get_sendmailcf();
+@oldlist = map { $_->[0] } &find_options("DaemonPortOptions", $conf);
+@newlist = map { { 'type' => 'O',
+ 'values' => [ " DaemonPortOptions=$_" ] } } @ports;
+&save_directives($conf, \@oldlist, \@newlist);
+&flush_file_lines($config{'sendmail_cf'});
+&unlock_file($config{'sendmail_cf'});
+
+# Update .mc file too, if we have one
+if ($features_access) {
+ @features = &list_features();
+ if (@features) {
+ &lock_file($config{'sendmail_mc'});
+ @dpa = grep { $_->{'type'} == 0 &&
+ $_->{'text'} =~ /^DAEMON_OPTIONS/ } @features;
+ for($i=0; $i<@dpa || $i<@ports; $i++) {
+ if ($dpa[$i] && $ports[$i]) {
+ # Modify
+ $dpa[$i]->{'text'} =
+ "DAEMON_OPTIONS(`$ports[$i]')";
+ &modify_feature($dpa[$i]);
+ }
+ elsif ($dpa[$i] && !$ports[$i]) {
+ # No longer needed .. delete
+ &delete_feature($dpa[$i]);
+ }
+ elsif (!$dpa[$i] && $ports[$i]) {
+ # Add new feature
+ $f = { 'type' => 0,
+ 'text' => "DAEMON_OPTIONS(`$ports[$i]')" };
+ &create_feature($f);
+ }
+ }
+ &unlock_file($config{'sendmail_mc'});
+ }
+ }
+
+# Restart Sendmail
+&restart_sendmail();
+&webmin_log("ports");
+&redirect("");
+
&init_config();
do '../ui-lib.pl';
%access = &get_module_acl();
-$features_access = $access{'opts'} && $access{'cws'} && $access{'masq'} && $access{'trusts'} && $access{'vmode'} && $access{'amode'} && $access{'omode'} && $access{'cgs'} && $access{'relay'} && $access{'mailers'} && $access{'access'} && $access{'domains'};
+$features_access = $access{'opts'} && $access{'ports'} && $access{'cws'} && $access{'masq'} && $access{'trusts'} && $access{'vmode'} && $access{'amode'} && $access{'omode'} && $access{'cgs'} && $access{'relay'} && $access{'mailers'} && $access{'access'} && $access{'domains'};
$config{'perpage'} ||= 20; # a value of 0 can cause problems
+@port_modifier_flags = ( 'a', 'b', 'c', 'f', 'h', 'C', 'E' );
# get_sendmailcf()
# Parses sendmail.cf and return a reference to an array of options.