mirror of
https://github.com/webmin/webmin.git
synced 2026-08-22 23:10:34 +01:00
Compare commits
11 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ce1ab74c6f | ||
|
|
77d817357d | ||
|
|
350908ed56 | ||
|
|
94ac2ff7d7 | ||
|
|
a24e5371b7 | ||
|
|
0810083588 | ||
|
|
2ec6cadbbd | ||
|
|
241abfe719 | ||
|
|
f78413549b | ||
|
|
b53cce9084 | ||
|
|
a92b52f502 |
@@ -1,5 +1,10 @@
|
|||||||
## Changelog
|
## Changelog
|
||||||
|
|
||||||
|
#### 2.641 (May 10, 2026)
|
||||||
|
* Fixed a bug when editing monitors in the System and Server Status module
|
||||||
|
* Fix Fail2Ban default jail options
|
||||||
|
* Added support for trusted proxy IP addresses
|
||||||
|
|
||||||
#### 2.640 (May 4, 2026)
|
#### 2.640 (May 4, 2026)
|
||||||
* Add new nftables module with profiles, saved tables, and chains/sets management
|
* Add new nftables module with profiles, saved tables, and chains/sets management
|
||||||
* Add new Nginx module with look and feel matching the Apache module
|
* Add new Nginx module with look and feel matching the Apache module
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@@ -528,7 +528,7 @@ if [ "$post_config" = "1" ]; then
|
|||||||
# Copy config file to /etc/webmin or /etc/usermin
|
# Copy config file to /etc/webmin or /etc/usermin
|
||||||
os_type=`grep "^os_type=" /etc/$product/config | sed -e 's/os_type=//g'`
|
os_type=`grep "^os_type=" /etc/$product/config | sed -e 's/os_type=//g'`
|
||||||
os_version=`grep "^os_version=" /etc/$product/config | sed -e 's/os_version=//g'`
|
os_version=`grep "^os_version=" /etc/$product/config | sed -e 's/os_version=//g'`
|
||||||
/usr/bin/perl /usr/share/$product/copyconfig.pl \$os_type \$os_version /usr/share/$product /etc/$product $mod
|
/usr/bin/perl /usr/share/$product/copyconfig.pl \$os_type \$os_version /usr/share/$product /etc/$product $mod >/dev/null
|
||||||
|
|
||||||
# Update the ACL for the root user, or the first user in the ACL
|
# Update the ACL for the root user, or the first user in the ACL
|
||||||
grep "^root:" /etc/$product/webmin.acl >/dev/null
|
grep "^root:" /etc/$product/webmin.acl >/dev/null
|
||||||
|
|||||||
@@ -492,7 +492,7 @@ if [ "$post_config" = "1" ]; then
|
|||||||
os_version=`grep "^os_version=" /etc/$prog/config | sed -e 's/os_version=//g'`
|
os_version=`grep "^os_version=" /etc/$prog/config | sed -e 's/os_version=//g'`
|
||||||
real_os_type=`grep "^real_os_type=" /etc/$prog/config | sed -e 's/real_os_type=//g'`
|
real_os_type=`grep "^real_os_type=" /etc/$prog/config | sed -e 's/real_os_type=//g'`
|
||||||
real_os_version=`grep "^real_os_version=" /etc/$prog/config | sed -e 's/real_os_version=//g'`
|
real_os_version=`grep "^real_os_version=" /etc/$prog/config | sed -e 's/real_os_version=//g'`
|
||||||
/usr/bin/perl /usr/libexec/$prog/copyconfig.pl "\$os_type/\$real_os_type" "\$os_version/\$real_os_version" /usr/libexec/$prog /etc/$prog $mod
|
/usr/bin/perl /usr/libexec/$prog/copyconfig.pl "\$os_type/\$real_os_type" "\$os_version/\$real_os_version" /usr/libexec/$prog /etc/$prog $mod >/dev/null
|
||||||
|
|
||||||
# Update the ACL for the root user, or the first user in the ACL
|
# Update the ACL for the root user, or the first user in the ACL
|
||||||
grep "^root:" /etc/$prog/webmin.acl >/dev/null
|
grep "^root:" /etc/$prog/webmin.acl >/dev/null
|
||||||
|
|||||||
106
miniserv.pl
106
miniserv.pl
@@ -1469,6 +1469,19 @@ if ($headerhost) {
|
|||||||
$headerhost = undef if (!&check_ipaddress($headerhost) &&
|
$headerhost = undef if (!&check_ipaddress($headerhost) &&
|
||||||
!&check_ip6address($headerhost));
|
!&check_ip6address($headerhost));
|
||||||
}
|
}
|
||||||
|
# If trusted_proxies is configured, header-supplied client IP and SSL
|
||||||
|
# client info are only honored when the direct TCP peer is in that list.
|
||||||
|
# Otherwise drop them so an attacker reaching miniserv directly cannot
|
||||||
|
# spoof X-Forwarded-For or X-SSL-Client-* to bypass auth.
|
||||||
|
if ($config{'trust_real_ip'} && $config{'trusted_proxies'} ne '' &&
|
||||||
|
!&ip_match($acptip, $localip,
|
||||||
|
split(/\s+/, $config{'trusted_proxies'}))) {
|
||||||
|
print DEBUG "handle_request: peer $acptip not in trusted_proxies; ".
|
||||||
|
"ignoring forwarding and SSL client headers\n";
|
||||||
|
$headerhost = undef;
|
||||||
|
delete $header{'x-ssl-client-dn'};
|
||||||
|
delete $header{'x-ssl-client-verify'};
|
||||||
|
}
|
||||||
if ($config{'trust_real_ip'}) {
|
if ($config{'trust_real_ip'}) {
|
||||||
$acpthost = $headerhost || $acpthost;
|
$acpthost = $headerhost || $acpthost;
|
||||||
if (&check_ipaddress($headerhost) || &check_ip6address($headerhost)) {
|
if (&check_ipaddress($headerhost) || &check_ip6address($headerhost)) {
|
||||||
@@ -1723,7 +1736,7 @@ if ($header{'user-agent'} =~ /webmin/i ||
|
|||||||
my $trust_ssl = $config{'trust_real_ip'} && !$config{'no_trust_ssl'};
|
my $trust_ssl = $config{'trust_real_ip'} && !$config{'no_trust_ssl'};
|
||||||
if ($use_ssl && $verified_client ||
|
if ($use_ssl && $verified_client ||
|
||||||
$trust_ssl && $header{'x-ssl-client-dn'} &&
|
$trust_ssl && $header{'x-ssl-client-dn'} &&
|
||||||
$header{'x-ssl-client-verify'} =~ /^success/i) {
|
$header{'x-ssl-client-verify'} =~ /^success$/i) {
|
||||||
if ($use_ssl && $verified_client) {
|
if ($use_ssl && $verified_client) {
|
||||||
$peername = Net::SSLeay::X509_NAME_oneline(
|
$peername = Net::SSLeay::X509_NAME_oneline(
|
||||||
Net::SSLeay::X509_get_subject_name(
|
Net::SSLeay::X509_get_subject_name(
|
||||||
@@ -1731,8 +1744,12 @@ if ($use_ssl && $verified_client ||
|
|||||||
$ssl_con)));
|
$ssl_con)));
|
||||||
$u = &find_user_by_cert($peername);
|
$u = &find_user_by_cert($peername);
|
||||||
}
|
}
|
||||||
if ($trust_ssl && !$u && $header{'x-ssl-client-dn'}) {
|
if ($trust_ssl && !$u && $header{'x-ssl-client-dn'} &&
|
||||||
# Use proxied client cert
|
!($use_ssl && $verified_client)) {
|
||||||
|
# Use proxied client cert (only when this connection
|
||||||
|
# is not itself a verified mTLS client; otherwise the
|
||||||
|
# header could be set by a real-cert client that didn't
|
||||||
|
# match a user, to authenticate as someone else).
|
||||||
$u = &find_user_by_cert($header{'x-ssl-client-dn'});
|
$u = &find_user_by_cert($header{'x-ssl-client-dn'});
|
||||||
}
|
}
|
||||||
if ($u) {
|
if ($u) {
|
||||||
@@ -4424,51 +4441,36 @@ if ($ok && (!$expired ||
|
|||||||
&run_login_script($authuser, $sid,
|
&run_login_script($authuser, $sid,
|
||||||
$loghost, $localip);
|
$loghost, $localip);
|
||||||
|
|
||||||
# Check for a redirect URL for the user
|
# Set cookie and redirect to originally requested page
|
||||||
local $rurl = &login_redirect($authuser, $pass, $host);
|
&write_data("HTTP/1.0 302 Moved Temporarily\r\n");
|
||||||
print DEBUG "handle_login: redirect URL rurl=$rurl\n";
|
&write_data("Date: $datestr\r\n");
|
||||||
if ($rurl) {
|
&write_data("Server: @{[&server_info()]}\r\n");
|
||||||
# Got one .. go to it
|
local $sec = $ssl ? "; secure" : "";
|
||||||
&write_data("HTTP/1.0 302 Moved Temporarily\r\n");
|
if (!$config{'no_httponly'}) {
|
||||||
&write_data("Date: $datestr\r\n");
|
$sec .= "; httpOnly";
|
||||||
&write_data("Server: @{[&server_info()]}\r\n");
|
}
|
||||||
&write_data("Location: $rurl\r\n");
|
if (!$config{'no_samesite'}) {
|
||||||
&write_keep_alive(0);
|
$sec .= "; SameSite=Lax";
|
||||||
&write_data("\r\n");
|
}
|
||||||
&log_request($loghost, $authuser, $reqline, 302, 0);
|
if ($in{'page'} !~ /^\/[A-Za-z0-9\/\.\-\_:]+$/) {
|
||||||
|
# Make redirect URL safe
|
||||||
|
$in{'page'} = "/";
|
||||||
|
}
|
||||||
|
local $cpath = $config{'cookiepath'};
|
||||||
|
if ($in{'save'}) {
|
||||||
|
&write_data("Set-Cookie: $sidname=$sid; path=$cpath; ".
|
||||||
|
"expires=\"Thu, 31-Dec-2037 00:00:00\"$sec\r\n");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
# Set cookie and redirect to originally requested page
|
&write_data("Set-Cookie: $sidname=$sid; path=$cpath".
|
||||||
&write_data("HTTP/1.0 302 Moved Temporarily\r\n");
|
"$sec\r\n");
|
||||||
&write_data("Date: $datestr\r\n");
|
|
||||||
&write_data("Server: @{[&server_info()]}\r\n");
|
|
||||||
local $sec = $ssl ? "; secure" : "";
|
|
||||||
if (!$config{'no_httponly'}) {
|
|
||||||
$sec .= "; httpOnly";
|
|
||||||
}
|
|
||||||
if (!$config{'no_samesite'}) {
|
|
||||||
$sec .= "; SameSite=Lax";
|
|
||||||
}
|
|
||||||
if ($in{'page'} !~ /^\/[A-Za-z0-9\/\.\-\_:]+$/) {
|
|
||||||
# Make redirect URL safe
|
|
||||||
$in{'page'} = "/";
|
|
||||||
}
|
|
||||||
local $cpath = $config{'cookiepath'};
|
|
||||||
if ($in{'save'}) {
|
|
||||||
&write_data("Set-Cookie: $sidname=$sid; path=$cpath; ".
|
|
||||||
"expires=\"Thu, 31-Dec-2037 00:00:00\"$sec\r\n");
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
&write_data("Set-Cookie: $sidname=$sid; path=$cpath".
|
|
||||||
"$sec\r\n");
|
|
||||||
}
|
|
||||||
&write_data("Location: $prot://$hostport$in{'page'}\r\n");
|
|
||||||
&write_keep_alive(0);
|
|
||||||
&write_data("\r\n");
|
|
||||||
&log_request($loghost, $authuser, $reqline, 302, 0);
|
|
||||||
syslog("info", "%s", "Successful login as $authuser from $loghost") if ($use_syslog);
|
|
||||||
&write_login_utmp($authuser, $acpthost);
|
|
||||||
}
|
}
|
||||||
|
&write_data("Location: $prot://$hostport$in{'page'}\r\n");
|
||||||
|
&write_keep_alive(0);
|
||||||
|
&write_data("\r\n");
|
||||||
|
&log_request($loghost, $authuser, $reqline, 302, 0);
|
||||||
|
syslog("info", "%s", "Successful login as $authuser from $loghost") if ($use_syslog);
|
||||||
|
&write_login_utmp($authuser, $acpthost);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
elsif ($ok && $expired &&
|
elsif ($ok && $expired &&
|
||||||
@@ -4980,20 +4982,6 @@ foreach my $c (keys %config) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
# login_redirect(username, password, host)
|
|
||||||
# Calls the login redirect script (if configured), which may output a URL to
|
|
||||||
# re-direct a user to after logging in.
|
|
||||||
sub login_redirect
|
|
||||||
{
|
|
||||||
return undef if (!$config{'login_redirect'});
|
|
||||||
local $quser = quotemeta($_[0]);
|
|
||||||
local $qpass = quotemeta($_[1]);
|
|
||||||
local $qhost = quotemeta($_[2]);
|
|
||||||
local $url = `$config{'login_redirect'} $quser $qpass $qhost`;
|
|
||||||
chop($url);
|
|
||||||
return $url;
|
|
||||||
}
|
|
||||||
|
|
||||||
# reload_config_file()
|
# reload_config_file()
|
||||||
# Re-read %config, and call post-config actions
|
# Re-read %config, and call post-config actions
|
||||||
sub reload_config_file
|
sub reload_config_file
|
||||||
|
|||||||
@@ -239,8 +239,8 @@ print &ui_table_row($text{'mon_ontimeout'},
|
|||||||
# When to run commands?
|
# When to run commands?
|
||||||
print &ui_table_row($text{'mon_cmdmode'},
|
print &ui_table_row($text{'mon_cmdmode'},
|
||||||
&ui_radio("cmdmode", $serv->{'cmdmode'} || 0,
|
&ui_radio("cmdmode", $serv->{'cmdmode'} || 0,
|
||||||
[ [ 0, text{'mon_cmdmode0'} ],
|
[ [ 0, $text{'mon_cmdmode0'} ],
|
||||||
[ 1, text{'mon_cmdmode1'} ] ]));
|
[ 1, $text{'mon_cmdmode1'} ] ]));
|
||||||
|
|
||||||
print &ui_table_row(" ", "<font size=-1>$text{'mon_oninfo'}</font>",
|
print &ui_table_row(" ", "<font size=-1>$text{'mon_oninfo'}</font>",
|
||||||
undef, \@tds);
|
undef, \@tds);
|
||||||
|
|||||||
@@ -456,9 +456,9 @@ if (!$config{'collect_notemp'} &&
|
|||||||
$a->[0] =~ /^Temperature$/i ||
|
$a->[0] =~ /^Temperature$/i ||
|
||||||
$a->[0] =~ /^Current\s+Drive\s+Temperature$/i ||
|
$a->[0] =~ /^Current\s+Drive\s+Temperature$/i ||
|
||||||
$a->[0] =~ /^Airflow\s+Temperature\s+Cel/i) &&
|
$a->[0] =~ /^Airflow\s+Temperature\s+Cel/i) &&
|
||||||
$a->[1] > 0) {
|
defined($a->[1]) && $a->[1] =~ /^\s*(\d+)/ && $1 > 0) {
|
||||||
push(@rv, { 'device' => $d->{'device'},
|
push(@rv, { 'device' => $d->{'device'},
|
||||||
'temp' => int($a->[1]),
|
'temp' => int($1),
|
||||||
'errors' => $st->{'errors'},
|
'errors' => $st->{'errors'},
|
||||||
'failed' => !$st->{'check'} });
|
'failed' => !$st->{'check'} });
|
||||||
last;
|
last;
|
||||||
|
|||||||
@@ -1,8 +1,5 @@
|
|||||||
#!/usr/local/bin/perl
|
#!/usr/local/bin/perl
|
||||||
|
|
||||||
local $format;
|
|
||||||
local $out;
|
|
||||||
|
|
||||||
require "./time-lib.pl";
|
require "./time-lib.pl";
|
||||||
use Time::Local;
|
use Time::Local;
|
||||||
|
|
||||||
@@ -17,17 +14,15 @@ $mode = "time";
|
|||||||
if ($in{'action'} eq $text{'action_sync'}) {
|
if ($in{'action'} eq $text{'action_sync'}) {
|
||||||
# Set system time to hardware time
|
# Set system time to hardware time
|
||||||
&error( $text{ 'acl_nosys' } ) if( $access{ 'sysdate' } );
|
&error( $text{ 'acl_nosys' } ) if( $access{ 'sysdate' } );
|
||||||
local $flags = &get_hwclock_flags();
|
$err = &set_system_time_to_hardware_time();
|
||||||
$out = &backquote_logged("hwclock $flags --hctosys");
|
&error( &text( 'error_sync', &html_escape($err) ) ) if ($err);
|
||||||
&error( &text( 'error_sync', $out ) ) if( $out ne "" );
|
|
||||||
&webmin_log("sync");
|
&webmin_log("sync");
|
||||||
|
|
||||||
} elsif ($in{'action'} eq $text{'action_sync_s'}) {
|
} elsif ($in{'action'} eq $text{'action_sync_s'}) {
|
||||||
# Set hardware time to system time
|
# Set hardware time to system time
|
||||||
&error( $text{ 'acl_nohw' } ) if( $access{ 'hwdate' } && $access{'sysdate'} );
|
&error( $text{ 'acl_nohw' } ) if( $access{ 'hwdate' } && $access{'sysdate'} );
|
||||||
local $flags = &get_hwclock_flags();
|
$err = &set_hardware_time_to_system_time();
|
||||||
$out = &backquote_logged("hwclock $flags --systohc");
|
&error( &text( 'error_sync', &html_escape($err) ) ) if ($err);
|
||||||
&error( &text( 'error_sync', $out ) ) if( $out ne "" );
|
|
||||||
&webmin_log("sync_s");
|
&webmin_log("sync_s");
|
||||||
|
|
||||||
} elsif($in{'action'} eq $text{'action_apply'} || $in{'mode'} eq 'sysdate' ) {
|
} elsif($in{'action'} eq $text{'action_apply'} || $in{'mode'} eq 'sysdate' ) {
|
||||||
@@ -111,4 +106,3 @@ if ($in{'action'} eq $text{'action_sync'}) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
&redirect("index.cgi?mode=$mode");
|
&redirect("index.cgi?mode=$mode");
|
||||||
|
|
||||||
|
|||||||
@@ -104,7 +104,7 @@ if ($support_hwtime) {
|
|||||||
print &tabletime(&hlink($text{'hw_title'}, "hardware_time"),
|
print &tabletime(&hlink($text{'hw_title'}, "hardware_time"),
|
||||||
0, %hw_date);
|
0, %hw_date);
|
||||||
print &ui_submit($text{'action_save'}, "action");
|
print &ui_submit($text{'action_save'}, "action");
|
||||||
if (support_hwtime()) {
|
if ($support_hwtime) {
|
||||||
print &ui_submit($text{'action_sync_s'}, "action");
|
print &ui_submit($text{'action_sync_s'}, "action");
|
||||||
}
|
}
|
||||||
print &ui_form_end();
|
print &ui_form_end();
|
||||||
@@ -153,7 +153,8 @@ if ($access{'timezone'} && &has_timezone()) {
|
|||||||
print &ui_tabs_end_tab();
|
print &ui_tabs_end_tab();
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( ( !$access{ 'sysdate' } && &has_command( "date" ) || !$access{ 'hwdate' } && &has_command( "hwclock" ) ) && $access{'ntp'} )
|
if (((!$access{'sysdate'} && &has_command("date")) ||
|
||||||
|
(!$access{'hwdate'} && $support_hwtime)) && $access{'ntp'})
|
||||||
{
|
{
|
||||||
# Show time server input
|
# Show time server input
|
||||||
print &ui_tabs_start_tab("mode", "sync");
|
print &ui_tabs_start_tab("mode", "sync");
|
||||||
|
|||||||
@@ -102,9 +102,10 @@ elsif ($?) {
|
|||||||
|
|
||||||
if ($hwtoo) {
|
if ($hwtoo) {
|
||||||
# Set hardware clock time to match system time (which is now correct)
|
# Set hardware clock time to match system time (which is now correct)
|
||||||
my $flags = &get_hwclock_flags();
|
if (&support_hwtime()) {
|
||||||
my $out = &backquote_logged("hwclock $flags --systohc");
|
my $err = &set_hardware_time_to_system_time();
|
||||||
return $? ? $out : undef;
|
return $err if ($err);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return undef;
|
return undef;
|
||||||
@@ -163,16 +164,34 @@ else {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# hwclock_command()
|
||||||
|
# Returns the path to the hwclock command, if available
|
||||||
|
sub hwclock_command
|
||||||
|
{
|
||||||
|
return &has_command("hwclock");
|
||||||
|
}
|
||||||
|
|
||||||
|
# hwclock_missing_error()
|
||||||
|
sub hwclock_missing_error
|
||||||
|
{
|
||||||
|
return &text('error_cnf', "hwclock");
|
||||||
|
}
|
||||||
|
|
||||||
# get_hardware_time()
|
# get_hardware_time()
|
||||||
# Returns the current hardware time, in localtime format. On failure returns
|
# Returns the current hardware time, in localtime format. On failure returns
|
||||||
# an empty array, and sets the global $get_hardware_time_error
|
# an empty array, and sets the global $get_hardware_time_error
|
||||||
sub get_hardware_time
|
sub get_hardware_time
|
||||||
{
|
{
|
||||||
|
my $hwclock = &hwclock_command();
|
||||||
|
$get_hardware_time_error = undef;
|
||||||
|
if (!$hwclock) {
|
||||||
|
$get_hardware_time_error = &hwclock_missing_error();
|
||||||
|
return ( );
|
||||||
|
}
|
||||||
my $flags = &get_hwclock_flags();
|
my $flags = &get_hwclock_flags();
|
||||||
$flags ||= "";
|
$flags ||= "";
|
||||||
$get_hardware_time_error = undef;
|
|
||||||
&clean_language();
|
&clean_language();
|
||||||
my $out = &backquote_command("hwclock $flags 2>/dev/null");
|
my $out = &backquote_command("$hwclock $flags 2>/dev/null");
|
||||||
&reset_environment();
|
&reset_environment();
|
||||||
if ($out =~ /^(\S+)\s+(\S+)\s+(\d+)\s+(\d+):(\d+):(\d+)\s+(\d+)\s+/) {
|
if ($out =~ /^(\S+)\s+(\S+)\s+(\d+)\s+(\d+):(\d+):(\d+)\s+(\d+)\s+/) {
|
||||||
return ($6, $5, $4, $3, &month_to_number($2), $7-1900, &weekday_to_number($1));
|
return ($6, $5, $4, $3, &month_to_number($2), $7-1900, &weekday_to_number($1));
|
||||||
@@ -186,7 +205,7 @@ elsif ($out =~ /^(\d+)\-(\d+)\-(\d+)\s+(\d+):(\d+):(\d+)/) {
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
$get_hardware_time_error = &text('index_ehwclock',
|
$get_hardware_time_error = &text('index_ehwclock',
|
||||||
"<tt>".&html_escape("hwclock $flags")."</tt>",
|
"<tt>".&html_escape("$hwclock $flags")."</tt>",
|
||||||
"<pre>".&html_escape($out)."</pre>");
|
"<pre>".&html_escape($out)."</pre>");
|
||||||
return ( );
|
return ( );
|
||||||
}
|
}
|
||||||
@@ -203,15 +222,41 @@ return localtime(time());
|
|||||||
sub set_hardware_time
|
sub set_hardware_time
|
||||||
{
|
{
|
||||||
my ($second, $minute, $hour, $date, $month, $year) = @_;
|
my ($second, $minute, $hour, $date, $month, $year) = @_;
|
||||||
|
my $hwclock = &hwclock_command();
|
||||||
|
return &hwclock_missing_error() if (!$hwclock);
|
||||||
$month++;
|
$month++;
|
||||||
$year += 1900;
|
$year += 1900;
|
||||||
my $format = "--set --date=".
|
my $format = "--set --date=".
|
||||||
quotemeta("$year-$month-$date $hour:$minute:$second");
|
quotemeta("$year-$month-$date $hour:$minute:$second");
|
||||||
my $flags = &get_hwclock_flags();
|
my $flags = &get_hwclock_flags();
|
||||||
my $out = &backquote_logged("hwclock $flags $format 2>&1");
|
my $out = &backquote_logged("$hwclock $flags $format 2>&1");
|
||||||
return $? ? $out : undef;
|
return $? ? $out : undef;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# set_hardware_time_to_system_time()
|
||||||
|
# Sets the hardware time to the current system time
|
||||||
|
sub set_hardware_time_to_system_time
|
||||||
|
{
|
||||||
|
my $hwclock = &hwclock_command();
|
||||||
|
return &hwclock_missing_error() if (!$hwclock);
|
||||||
|
my $flags = &get_hwclock_flags();
|
||||||
|
$flags ||= "";
|
||||||
|
my $out = &backquote_logged("$hwclock $flags --systohc 2>&1");
|
||||||
|
return $? ? $out : undef;
|
||||||
|
}
|
||||||
|
|
||||||
|
# set_system_time_to_hardware_time()
|
||||||
|
# Sets the system time to the current hardware time
|
||||||
|
sub set_system_time_to_hardware_time
|
||||||
|
{
|
||||||
|
my $hwclock = &hwclock_command();
|
||||||
|
return &hwclock_missing_error() if (!$hwclock);
|
||||||
|
my $flags = &get_hwclock_flags();
|
||||||
|
$flags ||= "";
|
||||||
|
my $out = &backquote_logged("$hwclock $flags --hctosys 2>&1");
|
||||||
|
return $? || $out ne "" ? $out : undef;
|
||||||
|
}
|
||||||
|
|
||||||
# set_system_time(secs, mins, hours, day, month, year)
|
# set_system_time(secs, mins, hours, day, month, year)
|
||||||
sub set_system_time
|
sub set_system_time
|
||||||
{
|
{
|
||||||
@@ -278,8 +323,9 @@ return defined($_[0]) ? ucfirst($weekday_names[$_[0]]) : undef;
|
|||||||
# Returns 1 if this system supports setting the hardware clock.
|
# Returns 1 if this system supports setting the hardware clock.
|
||||||
sub support_hwtime
|
sub support_hwtime
|
||||||
{
|
{
|
||||||
return &has_command("hwclock") &&
|
my $hwclock = &hwclock_command();
|
||||||
&execute_command("hwclock") == 0 &&
|
return $hwclock &&
|
||||||
|
&execute_command($hwclock) == 0 &&
|
||||||
!&running_in_xen() && !&running_in_vserver() &&
|
!&running_in_xen() && !&running_in_vserver() &&
|
||||||
!&running_in_openvz() && !&running_in_zone();
|
!&running_in_openvz() && !&running_in_zone();
|
||||||
}
|
}
|
||||||
@@ -307,4 +353,3 @@ if ($modconf_info) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
1;
|
1;
|
||||||
|
|
||||||
|
|||||||
@@ -11559,7 +11559,7 @@ my %access = &get_module_acl($u, $m, 1);
|
|||||||
return $access{'rbac'} ? 1 : 0;
|
return $access{'rbac'} ? 1 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
=head2 execute_command(command, stdin, stdout, stderr, translate-files?, safe?)
|
=head2 execute_command(command, stdin, stdout, stderr, translate-files?, safe?, logged?)
|
||||||
|
|
||||||
Runs some command, possibly feeding it input and capturing output to the
|
Runs some command, possibly feeding it input and capturing output to the
|
||||||
give files or scalar references. The parameters are :
|
give files or scalar references. The parameters are :
|
||||||
@@ -11576,16 +11576,19 @@ give files or scalar references. The parameters are :
|
|||||||
|
|
||||||
=item safe - Set to 1 if this command is safe and does not modify the state of the system.
|
=item safe - Set to 1 if this command is safe and does not modify the state of the system.
|
||||||
|
|
||||||
|
=item logged - Set to 1 if the command should be logged.
|
||||||
|
|
||||||
=cut
|
=cut
|
||||||
sub execute_command
|
sub execute_command
|
||||||
{
|
{
|
||||||
my ($cmd, $stdin, $stdout, $stderr, $trans, $safe) = @_;
|
my ($cmd, $stdin, $stdout, $stderr, $trans, $safe, $logged) = @_;
|
||||||
if (&is_readonly_mode() && !$safe) {
|
if (&is_readonly_mode() && !$safe) {
|
||||||
print STDERR "Vetoing command $_[0]\n";
|
print STDERR "Vetoing command $_[0]\n";
|
||||||
$? = 0;
|
$? = 0;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
$cmd = &translate_command($cmd);
|
$cmd = &translate_command($cmd);
|
||||||
|
&additional_log('exec', undef, $cmd) if ($logged);
|
||||||
|
|
||||||
# Use ` operator where possible
|
# Use ` operator where possible
|
||||||
&webmin_debug_log('CMD', "cmd=$cmd") if ($gconfig{'debug_what_cmd'});
|
&webmin_debug_log('CMD', "cmd=$cmd") if ($gconfig{'debug_what_cmd'});
|
||||||
@@ -11681,6 +11684,17 @@ waitpid($pid, 0);
|
|||||||
return $?;
|
return $?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
=head2 execute_command_logged(command, stdin, stdout, stderr, translate-files?, safe?)
|
||||||
|
|
||||||
|
Like execute_command, but also logs the command run.
|
||||||
|
|
||||||
|
=cut
|
||||||
|
sub execute_command_logged
|
||||||
|
{
|
||||||
|
my ($cmd, $stdin, $stdout, $stderr, $trans, $safe) = @_;
|
||||||
|
return &execute_command($cmd, $stdin, $stdout, $stderr, $trans, $safe, 1);
|
||||||
|
}
|
||||||
|
|
||||||
=head2 open_readfile(handle, file)
|
=head2 open_readfile(handle, file)
|
||||||
|
|
||||||
Opens some file for reading. Returns 1 on success, 0 on failure. Pretty much
|
Opens some file for reading. Returns 1 on success, 0 on failure. Pretty much
|
||||||
|
|||||||
@@ -30,6 +30,15 @@ if (!$@ && $in{'libwrap'}) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@tprox = split(/\s+/, $in{'trusted_proxies'});
|
||||||
|
foreach $h (@tprox) {
|
||||||
|
$err = &valid_allow($h);
|
||||||
|
&error($err) if ($err);
|
||||||
|
}
|
||||||
|
if ($in{'trust'} == 2 && !@tprox) {
|
||||||
|
&error($text{'access_etproxies'});
|
||||||
|
}
|
||||||
|
|
||||||
&lock_file($ENV{'MINISERV_CONFIG'});
|
&lock_file($ENV{'MINISERV_CONFIG'});
|
||||||
&get_miniserv_config(\%miniserv);
|
&get_miniserv_config(\%miniserv);
|
||||||
delete($miniserv{"allow"});
|
delete($miniserv{"allow"});
|
||||||
@@ -52,6 +61,7 @@ else {
|
|||||||
$miniserv{'trust_real_ip'} = 0;
|
$miniserv{'trust_real_ip'} = 0;
|
||||||
$miniserv{'no_trust_ssl'} = 1;
|
$miniserv{'no_trust_ssl'} = 1;
|
||||||
}
|
}
|
||||||
|
$miniserv{'trusted_proxies'} = join(' ', @tprox);
|
||||||
&put_miniserv_config(\%miniserv);
|
&put_miniserv_config(\%miniserv);
|
||||||
&unlock_file($ENV{'MINISERV_CONFIG'});
|
&unlock_file($ENV{'MINISERV_CONFIG'});
|
||||||
&show_restart_page();
|
&show_restart_page();
|
||||||
|
|||||||
@@ -38,6 +38,10 @@ print &ui_table_row(&hlink($text{'access_trust_lvl'}, "access_trust_lvl"),
|
|||||||
[ 1, $text{'access_trust_lvl1'} ],
|
[ 1, $text{'access_trust_lvl1'} ],
|
||||||
[ 2, $text{'access_trust_lvl2'} ] ]));
|
[ 2, $text{'access_trust_lvl2'} ] ]));
|
||||||
|
|
||||||
|
@tprox = split(/\s+/, $miniserv{'trusted_proxies'});
|
||||||
|
print &ui_table_row(&hlink($text{'access_tproxies'}, "access_tproxies"),
|
||||||
|
&ui_textarea("trusted_proxies", join("\n", @tprox), 4, 30));
|
||||||
|
|
||||||
eval "use Authen::Libwrap qw(hosts_ctl STRING_UNKNOWN)";
|
eval "use Authen::Libwrap qw(hosts_ctl STRING_UNKNOWN)";
|
||||||
if (!$@) {
|
if (!$@) {
|
||||||
print &ui_table_row($text{'access_libwrap'},
|
print &ui_table_row($text{'access_libwrap'},
|
||||||
|
|||||||
25
webmin/help/access_tproxies.html
Normal file
25
webmin/help/access_tproxies.html
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
<header>Trusted proxy addresses</header>
|
||||||
|
|
||||||
|
A list of IP addresses or networks (one per line, in the same format as the
|
||||||
|
allowed addresses field above) that are permitted to provide proxy headers
|
||||||
|
such as <tt>X-Forwarded-For</tt>, <tt>X-Real-IP</tt>, <tt>X-SSL-Client-DN</tt>
|
||||||
|
and <tt>X-SSL-Client-Verify</tt>.
|
||||||
|
|
||||||
|
<p>
|
||||||
|
When this list is set, headers received from any other peer are ignored,
|
||||||
|
preventing a client that can reach Webmin directly from spoofing its source
|
||||||
|
IP or impersonating a user via a fake SSL client certificate header.
|
||||||
|
|
||||||
|
<p>
|
||||||
|
This field is required when the trust level is set to trust both the remote
|
||||||
|
IP and SSL certificate provided by proxies. It is strongly recommended
|
||||||
|
whenever any proxy header trust is enabled.
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Example:
|
||||||
|
<pre>
|
||||||
|
10.0.0.5
|
||||||
|
192.168.1.0/24
|
||||||
|
2001:DB8::/32
|
||||||
|
</pre>
|
||||||
|
<p></p>
|
||||||
@@ -35,6 +35,8 @@ access_trust_lvl=Trust level for proxy headers
|
|||||||
access_trust_lvl0=No, do not trust any headers from the proxy
|
access_trust_lvl0=No, do not trust any headers from the proxy
|
||||||
access_trust_lvl1=Yes, trust the remote IP address provided by proxies
|
access_trust_lvl1=Yes, trust the remote IP address provided by proxies
|
||||||
access_trust_lvl2=Yes, trust both the remote IP and SSL cert provided by proxies
|
access_trust_lvl2=Yes, trust both the remote IP and SSL cert provided by proxies
|
||||||
|
access_tproxies=Trusted proxy addresses
|
||||||
|
access_etproxies=At least one trusted proxy address must be entered when trusting the remote IP and SSL cert from proxies
|
||||||
|
|
||||||
bind_title=Ports and Addresses
|
bind_title=Ports and Addresses
|
||||||
bind_desc2=This form can be used to change the port number that Webmin listens on, or have it listen on only a single IP address on your system. You can also configure it to accept connections on multiple ports, or to listen on several IP addresses. Note - your web browser may prompt you to log in again after changing the port or binding address.
|
bind_desc2=This form can be used to change the port number that Webmin listens on, or have it listen on only a single IP address on your system. You can also configure it to accept connections on multiple ports, or to listen on several IP addresses. Note - your web browser may prompt you to log in again after changing the port or binding address.
|
||||||
|
|||||||
Reference in New Issue
Block a user