mirror of
https://github.com/webmin/webmin.git
synced 2026-02-06 15:32:20 +00:00
Compare commits
59 Commits
2.401
...
dev/sessio
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f6b62525f8 | ||
|
|
57138d505b | ||
|
|
58580b7f4b | ||
|
|
d9a120c760 | ||
|
|
fb832eff82 | ||
|
|
75b0a6f7bb | ||
|
|
40707d8602 | ||
|
|
ac45266ee4 | ||
|
|
522aeb5264 | ||
|
|
1d24db1686 | ||
|
|
527043b54d | ||
|
|
56b62346b4 | ||
|
|
ee39f99d23 | ||
|
|
a223243db4 | ||
|
|
b59bdc4f1a | ||
|
|
d087f9f024 | ||
|
|
1607a59239 | ||
|
|
70589cf88a | ||
|
|
c429fbb202 | ||
|
|
f24375e13a | ||
|
|
d428f4d4c1 | ||
|
|
f0e07518c9 | ||
|
|
29709c3c51 | ||
|
|
fb71fbd5ae | ||
|
|
a1f06c5548 | ||
|
|
10e8a420c0 | ||
|
|
8149eef10a | ||
|
|
c4b98ef376 | ||
|
|
621d5c22bc | ||
|
|
98000bb007 | ||
|
|
d90a33bb0c | ||
|
|
d795fc7d60 | ||
|
|
b397ece0ab | ||
|
|
0a11f182b0 | ||
|
|
7c05368e8f | ||
|
|
49ceeebbf8 | ||
|
|
01867c86e0 | ||
|
|
008890dfa1 | ||
|
|
5d846e80b2 | ||
|
|
ce6bbe44ff | ||
|
|
3bc15788af | ||
|
|
faa5dddb0a | ||
|
|
55d03d426a | ||
|
|
da9aa22fa7 | ||
|
|
06ce137903 | ||
|
|
5462c3bbf8 | ||
|
|
bae4af7490 | ||
|
|
bfd2bfbc11 | ||
|
|
8de7fde8bb | ||
|
|
e5e8cde28e | ||
|
|
09d0b26aea | ||
|
|
87ba4dd181 | ||
|
|
282b28da5e | ||
|
|
d519c4099f | ||
|
|
0be73ac433 | ||
|
|
b0c029887f | ||
|
|
ce16f80848 | ||
|
|
cc407bc1c3 | ||
|
|
8e5633d9af |
12
CHANGELOG.md
12
CHANGELOG.md
@@ -1,5 +1,17 @@
|
||||
## Changelog
|
||||
|
||||
#### 2.403 (June 30, 2025)
|
||||
* Add support for the Webmin webserver to work in both HTTP and HTTPS modes at the same time
|
||||
* Add status monitor for PHP FPM #2499
|
||||
* Add support for redirecting to the enforced domain when the `musthost_redirect` directive is set
|
||||
* Add a UI API to mask sensitive text—like displayed passwords, unless hovered over container
|
||||
* Fix MySQL/MariaDB to remove obsolete `set-variable` options that break modern config files #2497
|
||||
|
||||
|
||||
#### 2.402 (June 16, 2025)
|
||||
* Update the Authentic theme to the latest version with various fixes and improvements
|
||||
* Fix support for EL10-based systems
|
||||
|
||||
#### 2.401 (June 2, 2025)
|
||||
* Add forgotten password recovery support for Virtualmin mailbox users
|
||||
* Add forgotten password recovery support in Usermin
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -26,82 +26,94 @@ $last_restart_time_flag = $module_var_directory."/restart-flag";
|
||||
# if the Apache binary changes, when Webmin is upgraded, or once every five
|
||||
# minutes if automatic rebuilding is enabled.
|
||||
if ($module_name ne 'htaccess') {
|
||||
local %oldsite;
|
||||
local $httpd = &find_httpd();
|
||||
local @st = stat($httpd);
|
||||
&read_file($site_file, \%oldsite);
|
||||
local @sst = stat($site_file);
|
||||
if ($oldsite{'path'} ne $httpd ||
|
||||
$oldsite{'size'} != $st[7] ||
|
||||
$oldsite{'webmin'} != &get_webmin_version() ||
|
||||
$config{'auto_mods'} && $sst[9] < time()-5*60) {
|
||||
# Need to build list of supported modules
|
||||
local ($ver, $mods, $fullver) = &httpd_info($httpd);
|
||||
if ($ver) {
|
||||
my @allmods = &available_modules();
|
||||
local @mods = map { "$_/$ver" }
|
||||
&configurable_modules(\@allmods);
|
||||
foreach my $m (@mods) {
|
||||
if ($m =~ /(\S+)\/(\S+)/) {
|
||||
$httpd_modules{$1} = $2;
|
||||
}
|
||||
}
|
||||
# Call again now that known modules have been set, as
|
||||
# sometimes there are dependencies due to LoadModule
|
||||
# statements in an IfModule block
|
||||
undef(@get_config_cache);
|
||||
@allmods = &available_modules();
|
||||
@mods = map { "$_/$ver" }
|
||||
&configurable_modules(\@allmods);
|
||||
local %site = ( 'size' => $st[7],
|
||||
'path' => $httpd,
|
||||
'modules' => join(' ', @mods),
|
||||
'allmodules' => join(' ', @allmods),
|
||||
'version' => $ver,
|
||||
'fullversion' => $fullver,
|
||||
'webmin' => &get_webmin_version() );
|
||||
&lock_file($site_file);
|
||||
&write_file($site_file, \%site);
|
||||
chmod(0644, $site_file);
|
||||
&unlock_file($site_file);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Read the site-specific setup file, then require in all the module-specific
|
||||
# .pl files
|
||||
if (&read_file($site_file, \%site)) {
|
||||
local($m, $f, $d);
|
||||
$httpd_size = $site{'size'};
|
||||
foreach $m (split(/\s+/, $site{'modules'})) {
|
||||
if ($m =~ /(\S+)\/(\S+)/) {
|
||||
$httpd_modules{$1} = $2;
|
||||
}
|
||||
}
|
||||
foreach $m (split(/\s+/, $site{'allmodules'})) {
|
||||
$all_httpd_modules{$m} = $site{'version'};
|
||||
}
|
||||
foreach $m (keys %httpd_modules) {
|
||||
if (!-r "$module_root_directory/$m.pl") {
|
||||
delete($httpd_modules{$m});
|
||||
}
|
||||
}
|
||||
foreach $f (split(/\s+/, $site{'htaccess'})) {
|
||||
if (-r $f) { push(@htaccess_files, $f); }
|
||||
}
|
||||
foreach $m (keys %httpd_modules) {
|
||||
do "$m.pl";
|
||||
}
|
||||
foreach $d (split(/\s+/, $site{'defines'})) {
|
||||
$httpd_defines{$d}++;
|
||||
}
|
||||
&create_site_file();
|
||||
}
|
||||
&read_site_file();
|
||||
|
||||
$apache_docbase = $config{'apache_docbase'} ? $config{'apache_docbase'} :
|
||||
$httpd_modules{'core'} >= 2.0 ?
|
||||
"http://httpd.apache.org/docs-2.0/mod/" :
|
||||
"http://httpd.apache.org/docs/mod/";
|
||||
|
||||
# create_site_file()
|
||||
# If the Apache binary or Webmin version has changed, create the site
|
||||
# file containing all known Apache modules
|
||||
sub create_site_file
|
||||
{
|
||||
my %oldsite;
|
||||
my $httpd = &find_httpd();
|
||||
my @st = stat($httpd);
|
||||
&read_file($site_file, \%oldsite);
|
||||
my @sst = stat($site_file);
|
||||
if ($oldsite{'path'} ne $httpd ||
|
||||
$oldsite{'size'} != $st[7] ||
|
||||
$oldsite{'webmin'} != &get_webmin_version() ||
|
||||
$config{'auto_mods'} && $sst[9] < time()-5*60) {
|
||||
# Need to build list of supported modules
|
||||
my ($ver, $mods, $fullver) = &httpd_info($httpd);
|
||||
if ($ver) {
|
||||
my @allmods = &available_modules();
|
||||
my @mods = map { "$_/$ver" }
|
||||
&configurable_modules(\@allmods);
|
||||
foreach my $m (@mods) {
|
||||
if ($m =~ /(\S+)\/(\S+)/) {
|
||||
$httpd_modules{$1} = $2;
|
||||
}
|
||||
}
|
||||
# Call again now that known modules have been set, as
|
||||
# sometimes there are dependencies due to LoadModule
|
||||
# statements in an IfModule block
|
||||
undef(@get_config_cache);
|
||||
@allmods = &available_modules();
|
||||
@mods = map { "$_/$ver" }
|
||||
&configurable_modules(\@allmods);
|
||||
my %site = ( 'size' => $st[7],
|
||||
'path' => $httpd,
|
||||
'modules' => join(' ', @mods),
|
||||
'allmodules' => join(' ', @allmods),
|
||||
'version' => $ver,
|
||||
'fullversion' => $fullver,
|
||||
'webmin' => &get_webmin_version() );
|
||||
&lock_file($site_file);
|
||||
&write_file($site_file, \%site);
|
||||
chmod(0644, $site_file);
|
||||
&unlock_file($site_file);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# read_site_file()
|
||||
# Read the site-specific setup file, then require in all the module-specific
|
||||
# .pl files
|
||||
sub read_site_file
|
||||
{
|
||||
if (&read_file($site_file, \%site)) {
|
||||
foreach my $m (split(/\s+/, $site{'modules'})) {
|
||||
if ($m =~ /(\S+)\/(\S+)/) {
|
||||
$httpd_modules{$1} = $2;
|
||||
}
|
||||
}
|
||||
foreach my $m (split(/\s+/, $site{'allmodules'})) {
|
||||
$all_httpd_modules{$m} = $site{'version'};
|
||||
}
|
||||
foreach my $m (keys %httpd_modules) {
|
||||
if (!-r "$module_root_directory/$m.pl") {
|
||||
delete($httpd_modules{$m});
|
||||
}
|
||||
}
|
||||
foreach my $f (split(/\s+/, $site{'htaccess'})) {
|
||||
if (-r $f) { push(@htaccess_files, $f); }
|
||||
}
|
||||
foreach my $m (keys %httpd_modules) {
|
||||
do "$m.pl";
|
||||
}
|
||||
foreach my $d (split(/\s+/, $site{'defines'})) {
|
||||
$httpd_defines{$d}++;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
# parse_config_file(handle, lines, file, [recursive])
|
||||
# Parses lines of text from some config file into a data structure. The
|
||||
# return value is an array of references, one for each directive in the file.
|
||||
@@ -2274,5 +2286,15 @@ sub format_config_allowed
|
||||
return $config{'format_config'};
|
||||
}
|
||||
|
||||
# clear_apache_modules_cache()
|
||||
# If new Apache modules were enabled, force re-gen of the site file
|
||||
# that contains the modules cache
|
||||
sub clear_apache_modules_cache
|
||||
{
|
||||
&unlink_file($site_file);
|
||||
&create_site_file();
|
||||
&read_site_file();
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ foreach $m (@mods) {
|
||||
}
|
||||
|
||||
# Force re-detection of modules
|
||||
unlink($site_file);
|
||||
&clear_apache_modules_cache();
|
||||
|
||||
# Force restart Apache
|
||||
if ($changed && &is_apache_running()) {
|
||||
|
||||
@@ -64,7 +64,7 @@ sub run
|
||||
};
|
||||
root($o->{'config'}, \&$conf_check);
|
||||
my $service = ($o->{'config'} =~ /usermin/ ? 'usermin' : 'webmin');
|
||||
my $systemctlcmd = `which systemctl`;
|
||||
my $systemctlcmd = &has_command('systemctl');
|
||||
$systemctlcmd =~ s/\s+$//;
|
||||
if ($o->{'cmd'} =~ /^(start|stop|restart|reload)$/) {
|
||||
my $rs = system("$o->{'config'}/$o->{'cmd'} $service");
|
||||
|
||||
@@ -95,8 +95,10 @@ sub main {
|
||||
undef, 1, undef, undef, 5);
|
||||
if ($latest_known_versions_remote &&
|
||||
!$latest_known_versions_remote_error) {
|
||||
%versions_remote = map{split /=/, $_}
|
||||
(split(/\n/, $latest_known_versions_remote));
|
||||
%versions_remote = map {
|
||||
my ($k, $v) = split(/=/, $_, 2);
|
||||
defined($v) ? ($k => $v) : ();
|
||||
} split(/\n/, $latest_known_versions_remote);
|
||||
} elsif ($latest_known_versions_remote_error) {
|
||||
say BRIGHT_YELLOW, "Warning: ", RESET, "Cannot fetch remote packages versions list - $latest_known_versions_remote_error";
|
||||
}
|
||||
|
||||
@@ -818,3 +818,8 @@ body > .mode > b[data-mode="server-manager"] > a > .ff-cloudmin {
|
||||
[data-pro-disabled$="-elem"] a:hover {
|
||||
filter: grayscale(1) contrast(1);
|
||||
}
|
||||
.not-secure {
|
||||
color: #f00a38;
|
||||
float: right;
|
||||
cursor: help;
|
||||
}
|
||||
|
||||
3
lang/en
3
lang/en
@@ -189,6 +189,9 @@ pam_mesg2=You must respond to the question below to login.
|
||||
pam_login=Continue
|
||||
pam_restart=Restart
|
||||
|
||||
login_notsecure=Not Secure
|
||||
login_notsecure_desc=This connection is not secure and could let a man-in-the-middle attack intercept your password or session cookie. Use HTTPS unless you are on a trusted local network or behind a secure reverse proxy.
|
||||
|
||||
acl_root=Root directory for file chooser
|
||||
acl_otherdirs=Other visible directories in file chooser
|
||||
acl_nodot=Hide dot files in file chooser?
|
||||
|
||||
61
makedist.pl
61
makedist.pl
@@ -1,34 +1,28 @@
|
||||
#!/usr/local/bin/perl
|
||||
# Builds a tar.gz package of a specified Webmin version
|
||||
|
||||
if ($0 =~ /^(.*)\//) {
|
||||
chdir($1);
|
||||
}
|
||||
@ARGV == 1 || @ARGV == 2 || @ARGV == 3 || usage();
|
||||
if ($ARGV[0] eq "-minimal" || $ARGV[0] eq "--minimal") {
|
||||
$min++;
|
||||
shift(@ARGV);
|
||||
}
|
||||
if ($ARGV[0] =~ /^--exclude-modules/) {
|
||||
$exclude_modules = $ARGV[0];
|
||||
shift(@ARGV);
|
||||
}
|
||||
if ($ARGV[0] =~ /^--product-type/) {
|
||||
$product_type = $ARGV[0];
|
||||
$product_type =~ s/--product-type=//;
|
||||
if ($product_type =~ /^(minimal|essential)$/) {
|
||||
$product_suff = "-$product_type";
|
||||
$product_pref = "$product_type-";
|
||||
# Parse command line options
|
||||
$mod_list = 'full';
|
||||
@ARGV = map { /^--\S+\s+/ ? split(/\s+/, $_) : $_ } @ARGV;
|
||||
while (@ARGV && $ARGV[0] =~ /^--?/) {
|
||||
my $opt = shift(@ARGV);
|
||||
if ($opt eq '--minimal' || $opt eq '-minimal') {
|
||||
$min = 1;
|
||||
next;
|
||||
}
|
||||
shift(@ARGV);
|
||||
if ($opt eq '--mod-list') {
|
||||
$mod_list = shift(@ARGV) // usage();
|
||||
next;
|
||||
}
|
||||
usage();
|
||||
}
|
||||
@ARGV == 1 || usage();
|
||||
$fullvers = $ARGV[0];
|
||||
$fullvers =~ /^([0-9\.]+)(\-(\d+))?$/ || usage();
|
||||
$vers = $1;
|
||||
$release = $3;
|
||||
$tardir = $min ? "minimal" : "tarballs";
|
||||
$vfile = $product_pref ? "$product_pref$fullvers" : $min ? "$fullvers-minimal" : $fullvers;
|
||||
$zipdir = "zips";
|
||||
$fullvers =~ /^([0-9\.]+)(?:-(\d+))?$/ || usage();
|
||||
($vers, $release) = ($1, $2);
|
||||
$tardir = $min ? 'minimal' : 'tarballs';
|
||||
$vfile = $min ? "$fullvers-minimal" : $fullvers;
|
||||
$zipdir = 'zips';
|
||||
$vers || usage();
|
||||
|
||||
@files = ("config.cgi", "config-*-linux",
|
||||
@@ -70,20 +64,15 @@ if ($min) {
|
||||
}
|
||||
else {
|
||||
# All the modules
|
||||
my $mod_def_list;
|
||||
my $mods_list;
|
||||
my $curr_dir = $0;
|
||||
($curr_dir) = $curr_dir =~ /^(.+)\/[^\/]+$/;
|
||||
$curr_dir = "." if ($curr_dir !~ /^\//);
|
||||
open(my $fh, '<', "$curr_dir/mod_def_list.txt") || die "Error opening \"mod_def_list.txt\" : $!\n";
|
||||
$mod_def_list = do { local $/; <$fh> };
|
||||
open(my $fh, '<', "$curr_dir/mod_${mod_list}_list.txt") ||
|
||||
die "Error opening \"mod_${mod_list}_list.txt\" : $!\n";
|
||||
$mods_list = do { local $/; <$fh> };
|
||||
close($fh);
|
||||
@mlist = split(/\s+/, $mod_def_list);
|
||||
if ($exclude_modules) {
|
||||
$exclude_modules =~ s/--exclude-modules=//;
|
||||
my @mlist_excluded =
|
||||
grep { my $f = $_; ! grep $_ eq $f, split(',', $exclude_modules) } @mlist;
|
||||
@mlist = @mlist_excluded;
|
||||
}
|
||||
@mlist = split(/\s+/, $mods_list);
|
||||
}
|
||||
|
||||
# Build EOL data
|
||||
@@ -296,6 +285,6 @@ close(ARFILE);
|
||||
|
||||
sub usage
|
||||
{
|
||||
die "usage: makedist.pl [-minimal] [--exclude-modules] <version>";
|
||||
die "Usage: $0 [--minimal] [--mod-list type] <version>\n";
|
||||
}
|
||||
|
||||
|
||||
@@ -29,6 +29,8 @@ my ($force_theme, $url, $upstream, $debdepends, $debrecommends,
|
||||
$no_prefix, $force_usermin, $release, $allow_overwrite, $final_mod,
|
||||
$dsc_file, $dir, $ver, @exclude);
|
||||
|
||||
my $mod_list = 'full';
|
||||
|
||||
while(@ARGV) {
|
||||
my $a = shift(@ARGV);
|
||||
if ($a eq "--deb-depends") {
|
||||
@@ -79,6 +81,9 @@ while(@ARGV) {
|
||||
elsif ($a eq "--exclude") {
|
||||
push(@exclude, shift(@ARGV));
|
||||
}
|
||||
elsif ($a eq "--mod-list") {
|
||||
$mod_list = shift(@ARGV);
|
||||
}
|
||||
elsif ($a =~ /^\-\-/) {
|
||||
print STDERR "Unknown option $a\n";
|
||||
exit(1);
|
||||
@@ -113,6 +118,7 @@ if (!$dir) {
|
||||
print " [--dsc-file file.dsc]\n";
|
||||
print " [--force-theme]\n";
|
||||
print " [--exclude file-or-dir]\n";
|
||||
print " [--mod-list full|core|minimal]\n";
|
||||
print RESET, "\n";
|
||||
exit(1);
|
||||
}
|
||||
@@ -246,7 +252,7 @@ if ($debdepends && exists($minfo{'depends'})) {
|
||||
my $curr_dir = $0;
|
||||
($curr_dir) = $curr_dir =~ /^(.+)\/[^\/]+$/;
|
||||
$curr_dir = "." if ($curr_dir !~ /^\//);
|
||||
my $mod_def_file = "$curr_dir/mod_def_list.txt";
|
||||
my $mod_def_file = "$curr_dir/mod_${mod_list}_list.txt";
|
||||
next if (! -r $mod_def_file);
|
||||
open(my $fh, '<', $mod_def_file) ||
|
||||
die "Error opening \"$mod_def_file\" : $!\n";
|
||||
@@ -279,7 +285,7 @@ if (exists($minfo{'deb_requires'})) {
|
||||
foreach my $debrequire (split(/\s+/, $minfo{'deb_requires'})) {
|
||||
push(@rrequires, $debrequire);
|
||||
}
|
||||
$rdeps .= ", " . join(", ", @rrequires) if (@rrequires);
|
||||
$rdeps .= ($rdeps ? ', ' : '') . join(", ", @rrequires) if (@rrequires);
|
||||
}
|
||||
|
||||
# Build (append) list of recommended packages (not Webmin modules)
|
||||
@@ -288,7 +294,8 @@ if (exists($minfo{'deb_recommends'})) {
|
||||
foreach my $debrecommend (split(/\s+/, $minfo{'deb_recommends'})) {
|
||||
push(@rrecommends, $debrecommend);
|
||||
}
|
||||
$rrecom .= ", " . join(", ", @rrecommends) if (@rrecommends);
|
||||
$rrecom .= ($rrecom ? ', ' : '') . join(", ", @rrecommends)
|
||||
if (@rrecommends);
|
||||
}
|
||||
|
||||
# Build (standalone) list of suggested packages (not Webmin modules)
|
||||
|
||||
@@ -32,10 +32,12 @@ my $release = 1;
|
||||
$ENV{'PATH'} = "/bin:/usr/bin:/usr/local/bin:/sbin:/usr/sbin";
|
||||
my $allow_overwrite = 0;
|
||||
|
||||
my ($force_theme, $rpmdepends, $rpmrecommends, $no_prefix, $set_prefix, $vendor,
|
||||
$url, $force_usermin, $final_mod, $sign, $keyname,
|
||||
my ($force_theme, $rpmdepends, $rpmrecommends, $no_prefix, $set_prefix,
|
||||
$obsolete_wbm, $vendor, $url, $force_usermin, $final_mod, $sign, $keyname,
|
||||
$epoch, $dir, $ver, @exclude);
|
||||
|
||||
my $mod_list = 'full';
|
||||
|
||||
# Parse command-line args
|
||||
while(@ARGV) {
|
||||
# XXX Untainting isn't needed when running as non-root?
|
||||
@@ -52,6 +54,12 @@ while(@ARGV) {
|
||||
elsif ($a eq "--no-prefix") {
|
||||
$no_prefix = 1;
|
||||
}
|
||||
elsif ($a eq "--prefix") {
|
||||
$set_prefix = &untaint(shift(@ARGV));
|
||||
}
|
||||
elsif ($a eq "--obsolete-wbm") {
|
||||
$obsolete_wbm = 1;
|
||||
}
|
||||
elsif ($a eq "--licence" || $a eq "--license") {
|
||||
$licence = &untaint(shift(@ARGV));
|
||||
}
|
||||
@@ -79,9 +87,6 @@ while(@ARGV) {
|
||||
elsif ($a eq "--rpm-dir") {
|
||||
$basedir = &untaint(shift(@ARGV));
|
||||
}
|
||||
elsif ($a eq "--prefix") {
|
||||
$set_prefix = &untaint(shift(@ARGV));
|
||||
}
|
||||
elsif ($a eq "--vendor") {
|
||||
$vendor = &untaint(shift(@ARGV));
|
||||
}
|
||||
@@ -97,6 +102,9 @@ while(@ARGV) {
|
||||
elsif ($a eq "--exclude") {
|
||||
push(@exclude, shift(@ARGV));
|
||||
}
|
||||
elsif ($a eq "--mod-list") {
|
||||
$mod_list = shift(@ARGV);
|
||||
}
|
||||
elsif ($a =~ /^\-\-/) {
|
||||
print STDERR "Unknown option $a\n";
|
||||
exit(1);
|
||||
@@ -121,6 +129,7 @@ if (!$dir) {
|
||||
print " [--rpm-dir directory]\n";
|
||||
print " [--no-prefix]\n";
|
||||
print " [--prefix prefix]\n";
|
||||
print " [--no-wbm-prefix]\n";
|
||||
print " [--vendor name]\n";
|
||||
print " [--licence name]\n";
|
||||
print " [--url url]\n";
|
||||
@@ -134,6 +143,7 @@ if (!$dir) {
|
||||
print " [--sign]\n";
|
||||
print " [--key keyname]\n";
|
||||
print " [--exclude file]\n";
|
||||
print " [--mod-list full|core|minimal]\n";
|
||||
print RESET, "\n";
|
||||
exit(1);
|
||||
}
|
||||
@@ -164,7 +174,8 @@ if (!-d $spec_dir || !-d $rpm_source_dir || !-d $rpm_dir) {
|
||||
|
||||
# Is this actually a module or theme directory?
|
||||
-d $source_dir || die "$dir is not a directory";
|
||||
my ($depends, $prefix, $desc, $prog, $iver, $istheme, $post_config);
|
||||
my ($depends, $prefix, $prefix_auto, $desc, $prog, $iver,
|
||||
$istheme, $post_config);
|
||||
if ($minfo{'desc'}) {
|
||||
$depends = join(" ", map { s/\/[0-9\.]+//; $_ }
|
||||
grep { !/^[0-9\.]+$/ }
|
||||
@@ -200,6 +211,7 @@ elsif ($tinfo{'desc'}) {
|
||||
else {
|
||||
die "$source_dir does not appear to be a webmin module or theme";
|
||||
}
|
||||
$prefix_auto = $prefix;
|
||||
$prefix = "" if ($no_prefix);
|
||||
$prefix = $set_prefix if ($set_prefix);
|
||||
my $ucprog = ucfirst($prog);
|
||||
@@ -267,7 +279,7 @@ if ($rpmdepends && defined($minfo{'depends'})) {
|
||||
my $curr_dir = $0;
|
||||
($curr_dir) = $curr_dir =~ /^(.+)\/[^\/]+$/;
|
||||
$curr_dir = "." if ($curr_dir !~ /^\//);
|
||||
my $mod_def_file = "$curr_dir/mod_def_list.txt";
|
||||
my $mod_def_file = "$curr_dir/mod_${mod_list}_list.txt";
|
||||
next if (! -r $mod_def_file);
|
||||
open(my $fh, '<', $mod_def_file) ||
|
||||
die "Error opening \"$mod_def_file\" : $!\n";
|
||||
@@ -300,7 +312,7 @@ if (exists($minfo{'rpm_requires'})) {
|
||||
foreach my $rpmrequire (split(/\s+/, $minfo{'rpm_requires'})) {
|
||||
push(@rrequires, $rpmrequire);
|
||||
}
|
||||
$rdeps .= " " . join(" ", @rrequires) if (@rrequires);
|
||||
$rdeps .= ($rdeps ? ' ' : '') . join(" ", @rrequires) if (@rrequires);
|
||||
}
|
||||
|
||||
# Build (append) list of recommended packages (not Webmin modules)
|
||||
@@ -309,7 +321,8 @@ if (exists($minfo{'rpm_recommends'})) {
|
||||
foreach my $rpmrecommend (split(/\s+/, $minfo{'rpm_recommends'})) {
|
||||
push(@rrecommends, $rpmrecommend);
|
||||
}
|
||||
$rrecom .= " " . join(" ", @rrecommends) if (@rrecommends);
|
||||
$rrecom .= ($rrecom ? ' ' : '') . join(" ", @rrecommends)
|
||||
if (@rrecommends);
|
||||
}
|
||||
|
||||
# Build (standalone) list of suggested packages (not Webmin modules)
|
||||
@@ -344,6 +357,12 @@ if (exists($minfo{'rpm_obsoletes'})) {
|
||||
}
|
||||
}
|
||||
|
||||
# Fix support for old module name prefixes
|
||||
if ($obsolete_wbm) {
|
||||
push(@rprovides, "$prefix_auto$mod");
|
||||
push(@robsoletes, "$prefix_auto$mod");
|
||||
}
|
||||
|
||||
# Create the SPEC file
|
||||
my $vendorheader = $vendor ? "Vendor: $vendor" : "";
|
||||
my $urlheader = $url ? "URL: $url" : "";
|
||||
@@ -360,7 +379,7 @@ Summary: $desc
|
||||
Name: $prefix$mod
|
||||
Version: $ver
|
||||
Release: $release
|
||||
Requires: /bin/sh /usr/bin/perl /usr/libexec/$prog $rdeps
|
||||
Requires: /bin/sh /usr/bin/perl $prog $rdeps
|
||||
EOF
|
||||
print $SPEC "Recommends: $rrecom\n" if ($rrecom);
|
||||
print $SPEC "Suggests: " . join(" ", @rsuggests) . "\n" if (@rsuggests);
|
||||
|
||||
@@ -90,7 +90,7 @@ Requires(pre): /usr/bin/perl
|
||||
Requires: /bin/sh /usr/bin/perl perl(lib) perl(open) perl(Net::SSLeay) perl(Time::Local) perl(Data::Dumper) perl(File::Path) perl(File::Basename) perl(Digest::SHA) perl(Digest::MD5) openssl unzip tar gzip
|
||||
Recommends: perl(DateTime) perl(DateTime::TimeZone) perl(DateTime::Locale) perl(Time::Piece) perl(Encode::Detect) perl(Time::HiRes) perl(Socket6) html2text shared-mime-info perl-File-Basename perl-File-Path perl-JSON-XS qrencode perl(DBI) perl(DBD::mysql)
|
||||
AutoReq: 0
|
||||
License: BSD-3-clause
|
||||
License: BSD-3-Clause
|
||||
Group: System/Tools
|
||||
Source: http://www.webmin.com/download/$tarfile
|
||||
Vendor: $rpm_maintainer
|
||||
|
||||
101
miniserv.pl
101
miniserv.pl
@@ -610,6 +610,53 @@ if ($config{'logclear'}) {
|
||||
push(@childpids, $logclearer);
|
||||
}
|
||||
|
||||
# session_state(session-id, set-state)
|
||||
# Sets or gets the active state of the client, which is used to determine
|
||||
# whether the client is away or not. This is used to allow for the session to
|
||||
# expire after a period of inactivity in case a client has opened connections or
|
||||
# makes HTTP requests in the background. Returns 1 if the client is currently
|
||||
# not away (ie. active), or 0 if it is away.
|
||||
sub session_state
|
||||
{
|
||||
my ($sid, $set) = @_;
|
||||
return 1 if (!$sid);
|
||||
|
||||
# Check session database
|
||||
my %sessiondb;
|
||||
dbmopen(%sessiondb, $config{'sessiondb'}, 0700);
|
||||
if ($@) {
|
||||
dbmclose(%sessiondb);
|
||||
eval "use NDBM_File";
|
||||
dbmopen(%sessiondb, $config{'sessiondb'}, 0700);
|
||||
}
|
||||
|
||||
# Get current record
|
||||
my $skey = &hash_session_id($sid);
|
||||
my ($user, $ltime, $ip, $lifetime, $active);
|
||||
if (exists($sessiondb{$skey})) {
|
||||
($user, $ltime, $ip, $lifetime, $active) =
|
||||
split(/\s+/, $sessiondb{$skey});
|
||||
$lifetime //= 0; # preserve or default to 0
|
||||
$active //= 1; # default to 'alive'
|
||||
}
|
||||
|
||||
# Update flag if caller supplied a value
|
||||
if ($user && $ltime && $ip && defined($set)) {
|
||||
$active = $set ? 1 : 0;
|
||||
$sessiondb{$skey} = join(' ', $user, $ltime, $ip, $lifetime, $active);
|
||||
print DEBUG "websocket updated status for $sid to $active\n";
|
||||
}
|
||||
else {
|
||||
print DEBUG "websocket current status for $sid is $active\n";
|
||||
}
|
||||
|
||||
# Save the record back to the database
|
||||
dbmclose(%sessiondb);
|
||||
|
||||
# Return the active state
|
||||
return $active;
|
||||
}
|
||||
|
||||
# Setup the logout time dbm if needed
|
||||
if ($config{'session'}) {
|
||||
eval "use SDBM_File";
|
||||
@@ -918,11 +965,27 @@ while(1) {
|
||||
|
||||
# Initialize SSL for this connection
|
||||
if ($use_ssl) {
|
||||
($ssl_con, $ssl_certfile,
|
||||
$ssl_keyfile) = &ssl_connection_for_ip(
|
||||
SOCK, $ipv6fhs{$s});
|
||||
print DEBUG "ssl_con returned $ssl_con\n";
|
||||
$ssl_con || exit;
|
||||
my $byte = '';
|
||||
# Look at the first byte of the socket
|
||||
# buffer but don't consume it
|
||||
recv(SOCK, $byte, 1, MSG_PEEK);
|
||||
if (length($byte) &&
|
||||
# Check if the first byte is a TLS
|
||||
(ord($byte) == 0x16 ||
|
||||
# Check if the first byte is SSL
|
||||
(ord($byte) & 0x80))) {
|
||||
($ssl_con,
|
||||
$ssl_certfile,
|
||||
$ssl_keyfile) =
|
||||
&ssl_connection_for_ip(
|
||||
SOCK, $ipv6fhs{$s});
|
||||
print DEBUG "ssl_con returned ".
|
||||
"$ssl_con\n";
|
||||
$ssl_con || exit;
|
||||
}
|
||||
else {
|
||||
$use_ssl = 0;
|
||||
}
|
||||
}
|
||||
|
||||
print DEBUG
|
||||
@@ -1101,8 +1164,10 @@ while(1) {
|
||||
print $outfd "0 0\n";
|
||||
}
|
||||
else {
|
||||
local ($user, $ltime, $ip, $lifetime) =
|
||||
local ($user, $ltime, $ip, $lifetime, $state) =
|
||||
split(/\s+/, $sessiondb{$skey});
|
||||
$lifetime //= 0;
|
||||
$state //= 1;
|
||||
local $lot = &get_logout_time($user, $session_id);
|
||||
if ($lot &&
|
||||
$time_now - $ltime > $lot*60 &&
|
||||
@@ -1131,7 +1196,7 @@ while(1) {
|
||||
# Session is OK, update last time
|
||||
# and remote IP
|
||||
print $outfd "2 $user\n";
|
||||
$sessiondb{$skey} = "$user $time_now $vip";
|
||||
$sessiondb{$skey} = "$user $time_now $vip $lifetime $state";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1520,7 +1585,8 @@ if (defined($header{'host'})) {
|
||||
else {
|
||||
$host = $header{'host'};
|
||||
}
|
||||
if ($config{'musthost'} && $host ne $config{'musthost'}) {
|
||||
if ($config{'musthost'} && $host ne $config{'musthost'} &&
|
||||
!$config{'musthost_redirect'}) {
|
||||
# Disallowed hostname used
|
||||
&http_error(400, "Invalid HTTP hostname");
|
||||
}
|
||||
@@ -1543,6 +1609,22 @@ if ($config{'redirect_prefix'}) {
|
||||
}
|
||||
$prot = $ssl ? "https" : "http";
|
||||
|
||||
# Redirect to the configured "musthost", if "musthost_redirect" is set, rather
|
||||
# than showing an error
|
||||
if ($config{'musthost'} && $host ne $config{'musthost'} &&
|
||||
$config{'musthost_redirect'}) {
|
||||
&write_data("HTTP/1.0 302 Moved Temporarily\r\n");
|
||||
&write_data("Date: $datestr\r\n");
|
||||
&write_data("Server: @{[&server_info()]}\r\n");
|
||||
&write_data("Location: $prot://$config{'musthost'}:$redirport\r\n");
|
||||
&write_keep_alive(0);
|
||||
&write_data("\r\n");
|
||||
&log_request($loghost, $authuser, $reqline, 302, 0) if $reqline;
|
||||
shutdown(SOCK, 1);
|
||||
close(SOCK);
|
||||
return;
|
||||
}
|
||||
|
||||
undef(%in);
|
||||
if ($page =~ /^([^\?]+)\?(.*)$/) {
|
||||
# There is some query string information
|
||||
@@ -5899,7 +5981,8 @@ while(1) {
|
||||
syswrite($fh, $buf, length($buf)) || last;
|
||||
}
|
||||
my $now = time();
|
||||
if ($now - $last_session_check_time > 10) {
|
||||
if ($now - $last_session_check_time > 10 &&
|
||||
&session_state($session_id) == 1) {
|
||||
# Re-validate the browser session every 10 seconds
|
||||
print DEBUG "verifying websockets session $session_id\n";
|
||||
print $PASSINw "verify $session_id 0 $acptip\n";
|
||||
|
||||
1
mod_core_list.txt
Normal file
1
mod_core_list.txt
Normal file
@@ -0,0 +1 @@
|
||||
acl apache authentic-theme backup-config bind8 change-user cron dovecot fail2ban fdisk filemin firewalld fsdump gray-theme htaccess-htpasswd init logrotate logviewer lvm mailboxes mailcap mount mysql net package-updates passwd phpini postfix proc procmail proftpd quota servers software spam sshd status system-status time updown useradmin usermin webmin webmincron webminlog xterm
|
||||
@@ -1 +0,0 @@
|
||||
cron dfsadmin exports inetd init mount samba useradmin fdisk format proc webmin quota software pap acl apache lpadmin bind8 sendmail squid bsdexports hpuxexports net dhcpd custom servers time syslog mysql man inittab raid postfix webminlog postgresql xinetd status cpan pam nis shell fetchmail passwd at proftpd sshd heartbeat cluster-software cluster-useradmin qmailadmin stunnel usermin fsdump lvm procmail cluster-webmin firewall sgiexports openslp webalizer shorewall adsl-client updown ppp-client pptp-server pptp-client ipsec ldap-useradmin change-user cluster-shell cluster-cron spam htaccess-htpasswd logrotate cluster-passwd mailboxes ipfw sarg bandwidth cluster-copy backup-config smart-status idmapd krb5 smf ipfilter rbac tunnel zones cluster-usermin dovecot syslog-ng mailcap ldap-client phpini filter bacula-backup ldap-server exim tcpwrappers package-updates system-status webmincron shorewall6 iscsi-server iscsi-client gray-theme iscsi-target iscsi-tgtd bsdfdisk fail2ban authentic-theme firewalld filemin firewall6 logviewer xterm
|
||||
1
mod_full_list.txt
Normal file
1
mod_full_list.txt
Normal file
@@ -0,0 +1 @@
|
||||
acl adsl-client apache at authentic-theme backup-config bacula-backup bandwidth bind8 bsdexports bsdfdisk change-user cluster-copy cluster-cron cluster-passwd cluster-shell cluster-software cluster-useradmin cluster-usermin cluster-webmin cpan cron custom dfsadmin dhcpd dovecot exim exports fail2ban fdisk fetchmail filemin filter firewall firewall6 firewalld format fsdump gray-theme heartbeat hpuxexports htaccess-htpasswd idmapd inetd init inittab ipfilter ipfw ipsec iscsi-client iscsi-server iscsi-target iscsi-tgtd krb5 ldap-client ldap-server ldap-useradmin logrotate logviewer lpadmin lvm mailboxes mailcap man mount mysql net nis openslp package-updates pam pap passwd phpini postfix postgresql ppp-client pptp-client pptp-server proc procmail proftpd qmailadmin quota raid rbac samba sarg sendmail servers sgiexports shell shorewall shorewall6 smart-status smf software spam squid sshd status stunnel syslog syslog-ng system-status tcpwrappers time tunnel updown useradmin usermin webalizer webmin webmincron webminlog xinetd xterm zones
|
||||
1
mod_minimal_list.txt
Normal file
1
mod_minimal_list.txt
Normal file
@@ -0,0 +1 @@
|
||||
acl cron init inittab man proc servers system-status webmin webmincron webminlog
|
||||
@@ -50,9 +50,10 @@ print &ui_table_row($text{'cnf_stor'},
|
||||
'NDB', 'ARCHIVE', 'CSV',
|
||||
'BLACKHOLE' ], 1, 0, 1));
|
||||
|
||||
my $ifpt_def_off = &get_innodb_file_per_table_default() ? 0 : 1;
|
||||
$fpt = &find_value("innodb_file_per_table", $mems);
|
||||
print &ui_table_row($text{'cnf_fpt'},
|
||||
&ui_yesno_radio("fpt", $fpt));
|
||||
&ui_yesno_radio("fpt", $fpt // $ifpt_def_off));
|
||||
|
||||
$ilt = &find_value("innodb_lock_wait_timeout", $mems);
|
||||
print &ui_table_row($text{'cnf_ilt'},
|
||||
|
||||
@@ -88,20 +88,13 @@ if ($mysql_version =~ /mariadb/i) {
|
||||
}
|
||||
&fix_mysql_text(\%text);
|
||||
|
||||
if (&compare_version_numbers($mysql_version, "5.5") >= 0) {
|
||||
@mysql_set_variables = ( "key_buffer_size", "sort_buffer_size",
|
||||
"net_buffer_length" );
|
||||
}
|
||||
else {
|
||||
@mysql_set_variables = ( "key_buffer", "sort_buffer",
|
||||
"net_buffer_length" );
|
||||
}
|
||||
if (&compare_version_numbers($mysql_version, "5.6") >= 0) {
|
||||
@mysql_number_variables = ( "table_open_cache", "max_connections" );
|
||||
}
|
||||
else {
|
||||
@mysql_number_variables = ( "table_cache", "max_connections" );
|
||||
}
|
||||
|
||||
@mysql_byte_variables = ( "max_allowed_packet" );
|
||||
my $mysql8_optout = &compare_version_numbers($mysql_version, "8.0") >= 0 && $mysql_version !~ /maria/i;
|
||||
if (!$mysql8_optout) {
|
||||
@@ -115,6 +108,15 @@ else {
|
||||
push(@mysql_set_variables, "myisam_sort_buffer_size");
|
||||
}
|
||||
|
||||
if (&compare_version_numbers($mysql_version, "5.5") >= 0) {
|
||||
push(@mysql_byte_variables, "key_buffer_size", "sort_buffer_size",
|
||||
"net_buffer_length");
|
||||
}
|
||||
else {
|
||||
@mysql_set_variables = ( "key_buffer", "sort_buffer",
|
||||
"net_buffer_length" );
|
||||
}
|
||||
|
||||
# make_authstr([login], [pass], [host], [port], [sock], [unix-user], [ssl])
|
||||
# Returns a string to pass to MySQL commands to login to the database
|
||||
sub make_authstr
|
||||
@@ -1766,6 +1768,18 @@ return
|
||||
$variant eq "mysql" && &compare_version_numbers($ver, "8.0") >= 0;
|
||||
}
|
||||
|
||||
# get_innodb_file_per_table_default()
|
||||
# Returns 1 if the InnoDB file-per-table option is disabled by default
|
||||
sub get_innodb_file_per_table_default
|
||||
{
|
||||
my ($ver, $variant) = &get_remote_mysql_variant();
|
||||
return
|
||||
($variant eq 'mariadb' && &compare_version_numbers($ver, '10.1.0') < 0) ||
|
||||
($variant eq 'mysql' && &compare_version_numbers($ver, '5.6.6') < 0)
|
||||
? 1
|
||||
: 0;
|
||||
}
|
||||
|
||||
# get_plugin_sql(version, variant, plainpass, plugin)
|
||||
# Get the right query for setting user password with plugin
|
||||
sub get_plugin_sql
|
||||
|
||||
@@ -18,7 +18,7 @@ else {
|
||||
$mysql_login ? "<tt>$mysql_login</tt>"
|
||||
: "<label>$text{'root_auto'}</label>");
|
||||
print &ui_table_row($text{'root_pass'},
|
||||
$mysql_pass ? "<tt>$mysql_pass</tt>"
|
||||
$mysql_pass ? "<tt>".&ui_text_mask($mysql_pass)."</tt>"
|
||||
: &ui_text_color($text{'root_none'}, 'danger'));
|
||||
print &ui_table_row($text{'root_newpass1'},
|
||||
&ui_password("newpass1", undef, 20));
|
||||
|
||||
@@ -13,6 +13,7 @@ foreach my $l (&get_all_mysqld_files()) {
|
||||
$conf = &get_mysql_config();
|
||||
($mysqld) = grep { $_->{'name'} eq 'mysqld' } @$conf;
|
||||
$mysqld || &error($text{'cnf_emysqld'});
|
||||
$mems = $mysqld->{'members'};
|
||||
|
||||
# Parse mysql server inputs
|
||||
if ($in{'port_def'}) {
|
||||
@@ -53,11 +54,9 @@ else {
|
||||
&save_directive($conf, $mysqld, "default-storage-engine",
|
||||
$in{'stor'} ? [ $in{'stor'} ] : [ ]);
|
||||
|
||||
$fpt = &find_value("innodb_file_per_table", $mems);
|
||||
if ($fpt || $in{'fpt'}) {
|
||||
&save_directive($conf, $mysqld, "innodb_file_per_table",
|
||||
[ $in{'fpt'} ]);
|
||||
}
|
||||
my $ifpt_def_off = &get_innodb_file_per_table_default();
|
||||
&save_directive($conf, $mysqld, "innodb_file_per_table",
|
||||
[ $in{'fpt'} ? ($ifpt_def_off ? 1 : undef) : 0 ]);
|
||||
|
||||
if ($in{'ilt_def'}) {
|
||||
&save_directive($conf, $mysqld, "innodb_lock_wait_timeout", [ ]);
|
||||
|
||||
@@ -72,7 +72,13 @@ print "$text{'pam_prefix'}\n";
|
||||
print &ui_form_start("@{[&get_webprefix()]}/pam_login.cgi", "post");
|
||||
print &ui_hidden("cid", $in{'cid'});
|
||||
|
||||
print &ui_table_start($text{'pam_header'},
|
||||
my $not_secure;
|
||||
if ($ENV{'HTTPS'} ne 'ON') {
|
||||
$not_secure = ui_tag('span', "⚠ $text{'login_notsecure'}",
|
||||
{ class => 'not-secure', title => $text{'login_notsecure_desc'} });
|
||||
}
|
||||
|
||||
print &ui_table_start($text{'pam_header'} . $not_secure,
|
||||
"width=40% class='loginform'", 2);
|
||||
|
||||
if ($gconfig{'realname'}) {
|
||||
|
||||
@@ -27,7 +27,8 @@ print &ui_form_end([ [ undef, $text{'opts_save'} ] ]);
|
||||
|
||||
# Header map contents
|
||||
print &ui_hr();
|
||||
if (&get_real_value("header_checks") eq "") {
|
||||
my $hc = &get_real_value("mime_header_checks");
|
||||
if ($hc eq "") {
|
||||
print $text{'opts_header_checks_no_map'},"<p>\n";
|
||||
} else {
|
||||
&generate_map_edit("header_checks", $text{'map_click'}." ".
|
||||
@@ -37,8 +38,11 @@ if (&get_real_value("header_checks") eq "") {
|
||||
|
||||
# MIME header map contents
|
||||
print &ui_hr();
|
||||
if (&get_real_value("mime_header_checks") eq "") {
|
||||
my $mhc = &get_real_value("mime_header_checks");
|
||||
if ($mhc eq "") {
|
||||
print $text{'opts_mime_header_checks_no_map'},"<p>\n";
|
||||
} elsif ($mhc eq $hc) {
|
||||
print $text{'opts_mime_header_checks_same_map'},"<p>\n";
|
||||
} else {
|
||||
&generate_map_edit("mime_header_checks", $text{'map_click'}." ".
|
||||
&hlink($text{'help_map_format'}, "header"), 1,
|
||||
|
||||
@@ -654,6 +654,7 @@ opts_header_checks=Header checking tables
|
||||
opts_mime_header_checks=MIME header checking tables
|
||||
opts_header_checks_no_map=(No header checking map is currently defined. Define a map first, then you can edit it)
|
||||
opts_mime_header_checks_no_map=(No MIME header checking map is currently defined. Define a map first, then you can edit it)
|
||||
opts_mime_header_checks_same_map=(MIME header checks are the same as regular header checks. Define a different map first, then you can edit it)
|
||||
header_name=Regular expression
|
||||
header_value=Action for matches
|
||||
header_discard=Discard (with log message..)
|
||||
@@ -868,6 +869,7 @@ opts_smtpd_tls_key_file=TLS private key file
|
||||
opts_smtpd_tls_CAfile=TLS certificate authority file
|
||||
opts_smtpd_use_tls=Enable TLS encryption?
|
||||
opts_smtp_enforce_tls=Require TLS encryption?
|
||||
opts_smtputf8_enable=Enable SMTPUTF8 support?
|
||||
sasl_err=Failed to save SMTP authentication and encryption
|
||||
sasl_ecert=Missing or invalid TLS certificate file
|
||||
sasl_ekey=Missing or invalid TLS key file
|
||||
|
||||
@@ -436,7 +436,7 @@ sub option_freefield
|
||||
sub option_yesno
|
||||
{
|
||||
my $name = $_[0];
|
||||
my $v = &get_current_value($name);
|
||||
my $v = &resolve_current_value($name);
|
||||
my $key = 'opts_'.$name;
|
||||
|
||||
print &ui_table_row(defined($_[1]) ? &hlink($text{$key}, "opt_".$name)
|
||||
|
||||
@@ -100,6 +100,11 @@ if (&compare_version_numbers($postfix_version, 3.3) >= 0) {
|
||||
&option_yesno("smtp_balance_inet_protocols");
|
||||
}
|
||||
|
||||
# SMTPUTF8 support
|
||||
if (&compare_version_numbers($postfix_version, 3.0) >= 0) {
|
||||
&option_yesno("smtputf8_enable");
|
||||
}
|
||||
|
||||
print &ui_table_end();
|
||||
print &ui_form_end([ [ undef, $text{'opts_save'} ] ]);
|
||||
|
||||
|
||||
@@ -91,7 +91,14 @@ print "$text{'session_prefix'}\n";
|
||||
|
||||
print &ui_form_start("@{[&get_webprefix()]}/session_login.cgi", "post");
|
||||
print &ui_hidden("page", $in{'page'});
|
||||
print &ui_table_start($text{'session_header'},
|
||||
|
||||
my $not_secure;
|
||||
if ($ENV{'HTTPS'} ne 'ON') {
|
||||
$not_secure = ui_tag('span', "⚠ $text{'login_notsecure'}",
|
||||
{ class => 'not-secure', title => $text{'login_notsecure_desc'} });
|
||||
}
|
||||
|
||||
print &ui_table_start($text{'session_header'} . $not_secure,
|
||||
"width=40% class='loginform'", 2);
|
||||
|
||||
# Login message
|
||||
|
||||
26
setup.sh
26
setup.sh
@@ -662,7 +662,7 @@ if [ ! -f "$config_dir/.pre-install" ]; then
|
||||
fi
|
||||
|
||||
# Test if we have systemd system
|
||||
systemctlcmd=$(which systemctl 2>/dev/null)
|
||||
systemctlcmd=$(command -v systemctl 2>/dev/null || :)
|
||||
if [ -x "$systemctlcmd" ]; then
|
||||
initsys=$(cat /proc/1/comm 2>/dev/null)
|
||||
if [ "$initsys" != "systemd" ]; then
|
||||
@@ -819,15 +819,27 @@ if [ "$upgrading" != 1 ]; then
|
||||
echo licence_module=$licence_module >>$config_dir/config
|
||||
fi
|
||||
|
||||
# Enable log rotation by default
|
||||
echo "logclear=1" >> $config_dir/miniserv.conf
|
||||
echo "logclear=1" >> $config_dir/config
|
||||
|
||||
# Enable HSTS by default
|
||||
echo "ssl_hsts=1" >> $config_dir/miniserv.conf
|
||||
|
||||
# Disallow unknown referers by default
|
||||
echo "referers_none=1" >>$config_dir/config
|
||||
else
|
||||
# one-off hack to set log variable in config from miniserv.conf
|
||||
grep log= $config_dir/config >/dev/null
|
||||
if [ "$?" = "1" ]; then
|
||||
grep log= $config_dir/miniserv.conf >> $config_dir/config
|
||||
grep logtime= $config_dir/miniserv.conf >> $config_dir/config
|
||||
grep logclear= $config_dir/miniserv.conf >> $config_dir/config
|
||||
# Enable log rotation if not set
|
||||
grep logclear= $config_dir/miniserv.conf >/dev/null
|
||||
if [ "$?" != "0" ]; then
|
||||
echo "logclear=1" >> $config_dir/miniserv.conf
|
||||
echo "logclear=1" >> $config_dir/config
|
||||
fi
|
||||
|
||||
# Enable HSTS by default if not set
|
||||
grep ssl_hsts= $config_dir/miniserv.conf >/dev/null
|
||||
if [ "$?" != "0" ]; then
|
||||
echo "ssl_hsts=1" >> $config_dir/miniserv.conf
|
||||
fi
|
||||
|
||||
# Disallow unknown referers if not set
|
||||
|
||||
@@ -97,7 +97,6 @@ if ($in{'need_unlink'}) {
|
||||
"delete_file.cgi?file=".
|
||||
&urlize($in{'file'})),"<p>\n";
|
||||
}
|
||||
print &ui_hr();
|
||||
&ui_print_footer("", $text{'index_return'});
|
||||
exit;
|
||||
}
|
||||
|
||||
@@ -119,6 +119,13 @@ while(<CMD>) {
|
||||
$pkg =~ s/\-\d.*$//; # Strip version number from end
|
||||
push(@rv, $pkg);
|
||||
}
|
||||
elsif (/\]\s+(Upgrading|Installing)\s+(\S+)/) {
|
||||
# Line like :
|
||||
# [3/8] Upgrading libcurl-0:8.11.1-5.fc42 100% ...
|
||||
local $pkg = $2;
|
||||
$pkg =~ s/:\d.*$//; # Strip version number from end
|
||||
push(@rv, $pkg);
|
||||
}
|
||||
if (!/ETA/ && !/\%\s+done\s+\d+\/\d+\s*$/) {
|
||||
print &html_escape($_."\n");
|
||||
}
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
# cfengine-monitor.pl
|
||||
# Monitor the cfengine daemon on this host
|
||||
|
||||
# Check the PID file to see if cfd is running
|
||||
sub get_cfengine_status
|
||||
{
|
||||
local %cconfig = &foreign_config($_[1]);
|
||||
&has_command($cconfig{'cfd'}) || return { 'up' => -1 };
|
||||
local @pids = &find_byname("cfd");
|
||||
if (@pids) {
|
||||
return { 'up' => 1 };
|
||||
}
|
||||
else {
|
||||
return { 'up' => 0 };
|
||||
}
|
||||
}
|
||||
|
||||
sub parse_cfengine_dialog
|
||||
{
|
||||
&depends_check($_[0], "cfengine");
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
@@ -33,7 +33,5 @@ else {
|
||||
&reset_environment();
|
||||
&webmin_log("refresh");
|
||||
print $text{'refresh_done'},"<p>\n";
|
||||
print &js_redirect("index.cgi");
|
||||
|
||||
&ui_print_footer("", $text{'index_return'});
|
||||
}
|
||||
|
||||
@@ -1,28 +0,0 @@
|
||||
# dnsadmin-monitor.pl
|
||||
# Monitor the BIND 4 DNS server on this host
|
||||
|
||||
# Check the PID file to see if BIND is running
|
||||
sub get_dnsadmin_status
|
||||
{
|
||||
return { 'up' => -1 } if (!&foreign_check($_[1]));
|
||||
&foreign_require($_[1], "dns-lib.pl");
|
||||
local %dconfig = &foreign_config($_[1]);
|
||||
return { 'up' => -1 } if (!-r $dconfig{'named_boot_file'});
|
||||
if (open(PID, "<".$dconfig{'named_pid_file'}) && <PID> =~ /(\d+)/ && kill(0, $1)) {
|
||||
close(PID);
|
||||
local @st = stat($dconfig{'named_pid_file'});
|
||||
return { 'up' => 1,
|
||||
'desc' => &text('up_since', scalar(localtime($st[9]))) };
|
||||
}
|
||||
else {
|
||||
return { 'up' => 0 };
|
||||
}
|
||||
}
|
||||
|
||||
sub parse_dnsadmin_dialog
|
||||
{
|
||||
&depends_check($_[0], "dnsadmin");
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
@@ -1,28 +0,0 @@
|
||||
# jabber-monitor.pl
|
||||
# Monitor the jabber server on this host
|
||||
|
||||
# Check the PID file to see if mon is running
|
||||
sub get_jabber_status
|
||||
{
|
||||
return { 'up' => -1 } if (!&foreign_check($_[1]));
|
||||
local %jconfig = &foreign_config($_[1]);
|
||||
-r $jconfig{'jabber_config'} || return { 'up' => -1 };
|
||||
&foreign_require($_[1], "jabber-lib.pl");
|
||||
local $pidfile = &foreign_call($_[1], "jabber_pid_file");
|
||||
if (open(PID, "<".$pidfile) && ($pid = int(<PID>)) && kill(0, $pid)) {
|
||||
return { 'up' => 1 };
|
||||
}
|
||||
else {
|
||||
return { 'up' => 0 };
|
||||
}
|
||||
}
|
||||
|
||||
sub parse_jabber_dialog
|
||||
{
|
||||
&depends_check($_[0], "jabber");
|
||||
eval "use XML::Parser";
|
||||
&error(&text('jabber_eparser', "<tt>XML::Parser</tt>")) if ($@);
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
@@ -25,7 +25,6 @@ type_inetd=Internet and RPC Server
|
||||
type_xinetd=Extended Internet Server
|
||||
type_squid=Squid Proxy Server
|
||||
type_bind8=BIND DNS Server
|
||||
type_dnsadmin=BIND 4 DNS Server
|
||||
type_dhcpd=DHCP Server
|
||||
type_tcp=TCP Connection
|
||||
type_http=HTTP Request
|
||||
@@ -51,12 +50,10 @@ type_change=File or Directory Change
|
||||
type_oldfile=File Not Changed
|
||||
type_qmailadmin=QMail Server
|
||||
type_mon=MON Service Monitor
|
||||
type_jabber=Jabber IM Server
|
||||
type_usermin=Usermin Webserver
|
||||
type_portsentry=Portsentry Daemon
|
||||
type_hostsentry=Hostsentry Daemon
|
||||
type_webmin=Webmin Webserver
|
||||
type_cfengine=Configuration Engine Daemon
|
||||
type_memory=Free Memory
|
||||
type_proftpd=ProFTPD Server
|
||||
type_dovecot=Dovecot IMAP/POP3 Server
|
||||
@@ -66,7 +63,6 @@ type_raid=RAID Device Status
|
||||
type_iface=Network Interface Status
|
||||
type_init=Bootup Action
|
||||
type_sensors=LM Sensor Status
|
||||
type_nut=NUT UPS Value
|
||||
type_mailq=Mail Queue Size
|
||||
type_dns=DNS Lookup
|
||||
type_query=SQL Query
|
||||
@@ -78,6 +74,7 @@ type_smtp=SMTP Connection
|
||||
type_imap=IMAP Connection
|
||||
type_firewalld=FirewallD Server
|
||||
type_reboot=Reboot Required
|
||||
type_phpini=PHP-FPM Server
|
||||
|
||||
mon_create=Create Monitor
|
||||
mon_edit=Edit Monitor
|
||||
@@ -333,8 +330,6 @@ acl_sched=Can change scheduled monitoring?
|
||||
|
||||
change_file=File or directory to monitor (fail if changed)
|
||||
|
||||
jabber_eparser=The Perl module $1 is not installed on your system.
|
||||
|
||||
memory_min2=Minimum free real memory
|
||||
memory_emin=Missing or invalid amount of free real memory
|
||||
memory_eproc=Webmin does not know how to check free memory on your operating system
|
||||
@@ -374,7 +369,7 @@ init_eaction=No action selected
|
||||
refresh_title=Refresh Status
|
||||
refresh_doing=Refreshing the status of all monitors ..
|
||||
refresh_doing2=Refreshing the status of $1 selected monitors ..
|
||||
refresh_done=.. done.
|
||||
refresh_done=.. done
|
||||
|
||||
sensors_name=Sensor to check
|
||||
sensors_value=Failed when
|
||||
@@ -387,17 +382,6 @@ sensors_cur=$1 (currently $2 $3)
|
||||
sensors_emin=Missing or invalid minimum value
|
||||
sensors_emax=Missing or invalid maximum value
|
||||
|
||||
nut_ups=NUT UPS to check
|
||||
nut_name=Attribute to check
|
||||
nut_value=Failed when
|
||||
nut_value1=Value is below $1
|
||||
nut_value2=Value is above $1
|
||||
nut_cmd=The command <tt>upsc</tt> is not installed on your system. This monitor requires the NUT package be installed and configured to operate.
|
||||
nut_eups=No USP to check entered
|
||||
nut_cur=$1 (currently $2)
|
||||
nut_emin=Missing or invalid minimum value
|
||||
nut_emax=Missing or invalid maximum value
|
||||
|
||||
mailq_system=Mail server
|
||||
mailq_qmailadmin=Qmail
|
||||
mailq_postfix=Postfix
|
||||
@@ -622,4 +606,11 @@ imap_euser=Missing IMAP login
|
||||
|
||||
reboot_pkgs=Package updates require a reboot
|
||||
|
||||
phpini_file=PHP-FPM version
|
||||
phpini_nofile=PHP-FPM configuration file not found!
|
||||
phpini_efile=No PHP-FPM version selected!
|
||||
phpini_noinit=No bootup action found for PHP-FPM version
|
||||
phpini_noinit2=Bootup action $1 does not exist!
|
||||
phpini_downinit=Bootup action $1 is down
|
||||
|
||||
__norefs=1
|
||||
|
||||
@@ -1,89 +0,0 @@
|
||||
# Check if some NUT value is too low or high
|
||||
|
||||
sub get_nut_status
|
||||
{
|
||||
return { 'up' => -1 } if (!&has_command("upsc"));
|
||||
local @sens = &get_ups_values($_[0]->{'ups'});
|
||||
local ($sens) = grep { $_->{'name'} eq $_[0]->{'name'} } @sens;
|
||||
return { 'up' => 1 } if (!$sens);
|
||||
if ($_[0]->{'mode'} == 1) {
|
||||
return $sens->{'value'} < $_[0]->{'min'} ? { 'up' => 0 }
|
||||
: { 'up' => 1 };
|
||||
}
|
||||
elsif ($_[0]->{'mode'} == 2) {
|
||||
return $sens->{'value'} > $_[0]->{'max'} ? { 'up' => 0 }
|
||||
: { 'up' => 1 };
|
||||
}
|
||||
}
|
||||
|
||||
sub show_nut_dialog
|
||||
{
|
||||
if (!&has_command("upsc")) {
|
||||
print &ui_table_row(undef, $text{'nut_cmd'}, 4);
|
||||
}
|
||||
else {
|
||||
# UPS name
|
||||
print &ui_table_row($text{'nut_ups'},
|
||||
&ui_textbox("ups", $_[0]->{'ups'}, 20));
|
||||
|
||||
# Value to check
|
||||
local @sens = &get_ups_values();
|
||||
if (@sens) {
|
||||
print &ui_table_row($text{'nut_name'},
|
||||
&ui_select("name", $_[0]->{'name'},
|
||||
[ map { [ $_->{'name'},
|
||||
&text('nut_cur', $_->{'name'}, $_->{'value'}) ] }
|
||||
@sens ]));
|
||||
}
|
||||
else {
|
||||
print &ui_table_row($text{'nut_name'},
|
||||
&ui_textbox("name", $_[0]->{'name'}, 20));
|
||||
}
|
||||
|
||||
# Expected value
|
||||
print &ui_table_row($text{'nut_value'},
|
||||
&ui_radio("mode", $_[0]->{'mode'} || 1,
|
||||
[ [ 1, &text('sensors_value1',
|
||||
&ui_textbox("min", $_[0]->{'min'}, 8)) ],
|
||||
[ 2, &text('sensors_value2',
|
||||
&ui_textbox("max", $_[0]->{'max'}, 8)) ] ]),
|
||||
3);
|
||||
}
|
||||
}
|
||||
|
||||
sub parse_nut_dialog
|
||||
{
|
||||
&has_command("upsc") || &error($text{'nut_cmd'});
|
||||
$in{'ups'} =~ /^\S+$/ || &error($text{'nut_eups'});
|
||||
$_[0]->{'ups'} = $in{'ups'};
|
||||
$_[0]->{'name'} = $in{'name'};
|
||||
$_[0]->{'mode'} = $in{'mode'};
|
||||
$_[0]->{'max'} = $in{'max'};
|
||||
$_[0]->{'min'} = $in{'min'};
|
||||
if ($in{'mode'} == 1) {
|
||||
$in{'min'} =~ /^[0-9\.\+\-]+$/ || &error($text{'nut_emin'});
|
||||
}
|
||||
elsif ($in{'mode'} == 2) {
|
||||
$in{'max'} =~ /^[0-9\.\+\-]+$/ || &error($text{'nut_emax'});
|
||||
}
|
||||
}
|
||||
|
||||
# get_ups_values(ups)
|
||||
# Returns a list of NUT attribute names and values for some UPS
|
||||
sub get_ups_values
|
||||
{
|
||||
if (!scalar(@get_ups_cache)) {
|
||||
local @rv;
|
||||
open(SENS, "upsc ".quotemeta($_[0])." 2>/dev/null |");
|
||||
while(<SENS>) {
|
||||
if (/^(\S+):\s+(.*)/) {
|
||||
push(@rv, { 'name' => $1,
|
||||
'value' => $2 });
|
||||
}
|
||||
}
|
||||
close(SENS);
|
||||
@get_ups_cache = @rv;
|
||||
}
|
||||
return @get_ups_cache;
|
||||
}
|
||||
|
||||
51
status/phpini-monitor.pl
Normal file
51
status/phpini-monitor.pl
Normal file
@@ -0,0 +1,51 @@
|
||||
# phpini-monitor.pl
|
||||
# Monitor a FPM-FPM server
|
||||
|
||||
sub get_phpini_status
|
||||
{
|
||||
my ($serv, $mod) = @_;
|
||||
return { 'up' => -1 } if (!&foreign_check("phpini"));
|
||||
return { 'up' => -1 } if (!&foreign_check("init"));
|
||||
&foreign_require("phpini");
|
||||
my @files = &phpini::list_php_configs();
|
||||
my ($file) = grep { $_->[0] eq $serv->{'inifile'} } @files;
|
||||
return { 'up' => -1,
|
||||
'desc' => $text{'phpini_nofile'} } if (!$file);
|
||||
my $init = &phpini::get_php_ini_bootup($serv->{'inifile'});
|
||||
return { 'up' => -1,
|
||||
'desc' => $text{'phpini_noinit'} } if (!$init);
|
||||
&foreign_require("init");
|
||||
my $st = &init::status_action($init);
|
||||
if ($st < 0) {
|
||||
return { 'up' => -1,
|
||||
'desc' => &text('phpini_noinit2', $init) };
|
||||
}
|
||||
elsif ($st > 0) {
|
||||
return { 'up' => 1 };
|
||||
}
|
||||
else {
|
||||
return { 'up' => 0,
|
||||
'desc' => &text('phpini_downinit', $init) };
|
||||
}
|
||||
}
|
||||
|
||||
sub show_phpini_dialog
|
||||
{
|
||||
my ($serv) = @_;
|
||||
&foreign_require("phpini");
|
||||
my @files = grep { $_->[1] }
|
||||
map { [ $_->[0], &phpini::get_php_ini_version($_->[0]) ] }
|
||||
&phpini::list_php_configs();
|
||||
my %donever;
|
||||
@files = grep { !$donever{$_->[1]}++ } @files;
|
||||
print &ui_table_row($text{'phpini_file'},
|
||||
&ui_select("inifile", $serv->{'inifile'}, \@files));
|
||||
}
|
||||
|
||||
sub parse_phpini_dialog
|
||||
{
|
||||
my ($serv) = @_;
|
||||
$in{'inifile'} || &error($text{'phpini_efile'});
|
||||
$serv->{'inifile'} = $in{'inifile'};
|
||||
}
|
||||
|
||||
51
ui-lib.pl
51
ui-lib.pl
@@ -3760,5 +3760,56 @@ my ($content, $attrs) = @_;
|
||||
return ui_tag('p', $content, $attrs);
|
||||
}
|
||||
|
||||
=head2 ui_text_mask(text, [tag], [extra_class])
|
||||
|
||||
Returns an HTML string with the given text hidden inside a tag that only shows
|
||||
on hover. If a second parameter is given, it is used as the outer tag that
|
||||
triggers the hover (default is "td"). If a third parameter is provided,
|
||||
it is added as an extra class to both the tag and its style.
|
||||
|
||||
=cut
|
||||
sub ui_text_mask
|
||||
{
|
||||
return &theme_ui_text_mask(@_) if (defined(&theme_ui_text_mask));
|
||||
my ($text, $tag, $extra_class) = @_;
|
||||
my $class = 'hover-mask';
|
||||
my $classcss = ".$class";
|
||||
if ($extra_class) {
|
||||
$class .= " $extra_class";
|
||||
$classcss .= ".$extra_class";
|
||||
}
|
||||
$tag ||= 'td';
|
||||
my $style_content = <<"CSS";
|
||||
x-ui-text-mask${classcss} {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
color: transparent;
|
||||
transition:color .25s ease;
|
||||
}
|
||||
x-ui-text-mask${classcss}::after{
|
||||
content: attr(data-mask);
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
color: var(--ui-password-mask-color, #000);
|
||||
pointer-events: none;
|
||||
transition: opacity .25s ease;
|
||||
}
|
||||
$tag:has(>*>x-ui-text-mask${classcss}):hover x-ui-text-mask${classcss},
|
||||
$tag:has(>x-ui-text-mask${classcss}):hover x-ui-text-mask${classcss}{
|
||||
color: inherit;
|
||||
}
|
||||
$tag:has(>*>x-ui-text-mask${classcss}):hover x-ui-text-mask${classcss}::after,
|
||||
$tag:has(>x-ui-text-mask${classcss}):hover x-ui-text-mask${classcss}::after{
|
||||
opacity: 0;
|
||||
}
|
||||
CSS
|
||||
my $rv = '';
|
||||
$rv .= &ui_tag('style', $style_content, { type => 'text/css' })
|
||||
if (!$main::ui_text_mask_donecss->{"$tag$class"}++);
|
||||
$rv .= &ui_tag('x-ui-text-mask', $text,
|
||||
{ 'class' => $class, 'data-mask' => '••••••••' });
|
||||
return $rv;
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
|
||||
@@ -1077,11 +1077,13 @@ sub PrintHeader
|
||||
{
|
||||
my ($cs, $mt, $headers) = @_;
|
||||
$mt ||= "text/html";
|
||||
if ($ENV{'SSL_HSTS'} == 1 && uc($ENV{'HTTPS'}) eq "ON") {
|
||||
print "Strict-Transport-Security: max-age=31536000;\n";
|
||||
}
|
||||
elsif (uc($ENV{'HTTPS'}) ne "ON") {
|
||||
print "Strict-Transport-Security: max-age=0;\n";
|
||||
if (uc($ENV{'HTTPS'}) eq "ON") {
|
||||
if ($ENV{'SSL_HSTS'}) {
|
||||
print "Strict-Transport-Security: max-age=31536000;\n";
|
||||
}
|
||||
else {
|
||||
print "Strict-Transport-Security: max-age=0;\n";
|
||||
}
|
||||
}
|
||||
if ($pragma_no_cache || $gconfig{'pragma_no_cache'}) {
|
||||
print "pragma: no-cache\n";
|
||||
@@ -2126,7 +2128,7 @@ if ($_[0] =~ /^\// || $_[0] =~ /^[a-z]:[\\\/]/i) {
|
||||
else {
|
||||
# Check each directory in the path
|
||||
my %donedir;
|
||||
foreach my $d (split($path_separator, $ENV{'PATH'})) {
|
||||
foreach my $d (split($path_separator || ":", $ENV{'PATH'})) {
|
||||
next if ($donedir{$d}++);
|
||||
$d =~ s/$slash$// if ($d ne $slash);
|
||||
my $t = &translate_filename("$d/$_[0]");
|
||||
|
||||
@@ -28,7 +28,7 @@ print &ui_table_row($text{'debug_file'},
|
||||
print &ui_table_row($text{'debug_size'},
|
||||
&ui_radio("debug_size_def", $gconfig{'debug_size'} ? 0 : 1,
|
||||
[ [ 1, $text{'default'}.
|
||||
" (".&nice_size($main::default_debug_log_size).")" ],
|
||||
" (".&html_strip(&nice_size($main::default_debug_log_size)).")" ],
|
||||
[ 0, &ui_bytesbox("debug_size", $gconfig{'debug_size'}) ] ]
|
||||
), undef, [ "valign=middle","valign=middle" ]);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user