Merge branch 'master' of github.com:webmin/webmin

This commit is contained in:
Jamie Cameron
2022-06-15 22:27:32 -07:00
24 changed files with 358 additions and 122 deletions

File diff suppressed because one or more lines are too long

View File

@@ -129,7 +129,7 @@ Disable proxy-related features in Webmin.
=head1 SYNOPSIS
disable-proxy [options]
webmin disable-proxy [options]
=head1 OPTIONS
@@ -146,14 +146,8 @@ C</etc/webmin>
=back
=head1 EXIT CODES
0 on success
non-0 on error
=head1 LICENSE AND COPYRIGHT
Copyright 2018 Jamie Cameron <jcameron@webmin.com>, Joe Cooper
<joe@virtualmin.com>.
Copyright 2022 Jamie Cameron <jcameron@webmin.com>
Joe Cooper <joe@virtualmin.com>

View File

@@ -87,7 +87,7 @@ second factor (e.g. phone or USB key) has been lost.
=head1 SYNOPSIS
disable-twofactor --user username
webmin disable-twofactor --user username
=head1 OPTIONS
@@ -106,16 +106,13 @@ C</etc/webmin>
Name of the user to disable two-factor authentication for.
=back
=head1 EXIT CODES
0 on successfully replacing configuration options
non-0 on error
=head1 LICENSE AND COPYRIGHT
Copyright 2018 Jamie Cameron <jcameron@webmin.com>, Joe Cooper
<joe@virtualmin.com>.
Copyright 2022 Jamie Cameron <jcameron@webmin.com>
Joe Cooper <joe@virtualmin.com>
Ilia Rostovtsev <ilia@virtualmin.com>

View File

@@ -134,7 +134,7 @@ Configure the Webmin web server to be proxied through another web server, like A
=head1 SYNOPSIS
enable-proxy [options]
webmin enable-proxy [options]
=head1 OPTIONS
@@ -161,14 +161,7 @@ domain.tld)
=back
=head1 EXIT CODES
0 on success
non-0 on error
=head1 LICENSE AND COPYRIGHT
Copyright 2018 Jamie Cameron <jcameron@webmin.com>, Joe Cooper
<joe@virtualmin.com>.
Copyright 2022 Jamie Cameron <jcameron@webmin.com>
Joe Cooper <joe@virtualmin.com>

View File

@@ -1784,7 +1784,7 @@ Manage Webmin/Usermin module language files (lang|ulang|help|config|uconfig|modu
=head1 SYNOPSIS
language-manager [options]
webmin language-manager [options]
=head1 OPTIONS
@@ -1798,35 +1798,35 @@ Examples of usage:
Synchronize all language keys for Apache module, based on template language. Newly added entries to Apache template language file (def. en), will be translated and inserted into all other machine translated language files, while deleted entries will also be removed on all targets (translations), including human translated files. The value for "defines_desc" will be force re-translated and translation will be done in HTML format.
- language-manager -m=apache -kft=defines_desc -kfh=defines_desc
- webmin language-manager -m=apache -kft=defines_desc -kfh=defines_desc
Synchronize all modules' "help/" language files. Newly added files will be translated and already translated, both human and machine translations, will be kept intact.
- language-manager -w=help
- webmin language-manager -w=help
Check for Software Packages module, all matching escaped HTML "&lt;" and "&gt;" entities in template file (def. en), and if found, make sure that translations (including machine translations) for the same key, contain exact escaped HTML entities, as on template string, rather than "<" or ">". Technically, it's possible to check and replace anything on language files using this command.
- language-manager -vf="&lt;:<,&gt;:>" -m=software
- webmin language-manager -vf="&lt;:<,&gt;:>" -m=software
Translate all available languages, using old-time encoding map, for BIND module, using as type "lang" directory, discarding human translations for Hebrew, keeping original value (not translating) for key "mass_desc", and printing verbose output.
- language-manager -x=full -e=map -m=bind8 -w=lang -se=he -ke=mass_desc
- webmin language-manager -x=full -e=map -m=bind8 -w=lang -se=he -ke=mass_desc
Transcode only and rename all modules' "help/" old-time format files. Old files, such as "ja_JP.euc.html", "ko_KR.euc.html", "zh_TW.Big5.html" and "ru_RU.html" will be automatically renamed and/or deleted.
- language-manager -w=help -e=map -ot
- webmin language-manager -w=help -e=map -ot
Only transcode language files, using old-time encoding map, from files being in different encodings, to new style, where all language files are in "utf-8" encoding, for Apache module. No translations will be made, and no ".auto" files will be created.
- language-manager -x=full -e=map -m=apache -ot
- webmin language-manager -x=full -e=map -m=apache -ot
Repare human translated language files, which stored in "utf-8" encoding already but still have HTML entities.
- language-manager -m=virtual-server -t=no,es -x=transcode
- webmin language-manager -m=virtual-server -t=no,es -x=transcode
Test translations for "index_stopmsg,trusted_warning" keys, in Russian and German languages, in BIND module, print on-screen results and exit.
- language-manager -m=bind8 -t=ru,de -kt=index_stopmsg,trusted_warning
- webmin language-manager -m=bind8 -t=ru,de -kt=index_stopmsg,trusted_warning
=item --mode, -x <sync|full|transcode>

View File

@@ -165,7 +165,7 @@ List one or all configuration directives for C<miniserv.conf> or a module C<conf
=head1 SYNOPSIS
list-config [options]
webmin list-config [options]
=head1 OPTIONS
@@ -192,16 +192,11 @@ Specify a single option to display. By default, the entire configuration file wi
Display the description of the option from the module C<config.info> file, instead of it's current value. This option is only available for modules, as miniserv.conf does not have a config.info.
=back
=head1 EXIT CODES
0 on success
non-0 on error
=head1 LICENSE AND COPYRIGHT
Copyright 2018 Jamie Cameron <jcameron@webmin.com>, Joe Cooper
<joe@virtualmin.com>.
Copyright 2022 Jamie Cameron <jcameron@webmin.com>
Joe Cooper <joe@virtualmin.com>

View File

@@ -18,7 +18,8 @@ sub main
GetOptions('help|h' => \$opt{'help'},
'config|c=s' => \$opt{'config'},
'user|u=s' => \$opt{'user'},
'password|p=s' => \$opt{'password'});
'password|p=s' => \$opt{'password'},
'stdout|o!' => \$opt{'stdout'});
# If username passed as regular param
my $user = scalar(@ARGV) == 1 && $ARGV[0];
@@ -71,8 +72,9 @@ sub change_password
my $root = root($confdif, \&$conf_check);
# Use pre-defined encryption (forced by Webmin config)
if ($gconfig->{'md5pass'} == 1 ||
$gconfig->{'md5pass'} == 2)
if (!$optref->{'stdout'} &&
($gconfig->{'md5pass'} == 1 ||
$gconfig->{'md5pass'} == 2))
{
do "$root/acl/md5-lib.pl";
@@ -160,6 +162,12 @@ sub change_password
# Update with new password and store timestamp
$uinfos{$user}->[0] = &$encrypt_password($pass, \%gconfig, \%config);
# Print the hash and exit
if ($optref->{'stdout'}) {
say $uinfos{$user}->[0];
exit 0;
}
$uinfos{$user}->[5] = time() if ($uinfos{$user}->[5]);
map {$ulines{$_} = join(":", @{ $uinfos{$_} })} keys %uinfos;
@@ -209,15 +217,15 @@ sub root
=head1 NAME
passwd
passwd
=head1 DESCRIPTION
This program allows you to change the password of a user in the Webmin password file
This program allows you to change the password of a user in the Webmin password file
=head1 SYNOPSIS
passwd [options]
webmin passwd [options]
=head1 OPTIONS
@@ -225,37 +233,32 @@ passwd [options]
=item --help, -h
Print this usage summary and exit.
Print this usage summary and exit.
Examples of usage:
- passwd root
- passwd --user root
- passwd --user root --password ycwyMQRVAZY
- passwd --config /usr/local/etc/webmin --user root --password ycwyMQRVAZY
Examples of usage:
- webmin passwd root
- webmin passwd --user root
- webmin passwd --user root --password ycwyMQRVAZY
- webmin passwd --config /usr/local/etc/webmin --user root --password ycwyMQRVAZY
- webmin passwd --config /usr/local/etc/webmin --user root --password ycwyMQRVAZY --stdout
=item --config, -c
Specify the full path to the Webmin configuration directory. Defaults to C</etc/webmin>
Specify the full path to the Webmin configuration directory. Defaults to C</etc/webmin>
=item --user, -u
Existing Webmin user to change password for
Existing Webmin user to change password for
=item --password, -p
Set new user password. Using this option may be unsecure.
=back
=head1 LICENSE AND COPYRIGHT
Copyright 2021 Jamie Cameron <jcameron@webmin.com>
Joe Cooper <joe@virtualmin.com>
Ilia Rostovtsev <ilia@virtualmin.com>
Copyright 2022 Jamie Cameron <jcameron@webmin.com>
Joe Cooper <joe@virtualmin.com>
Ilia Rostovtsev <ilia@virtualmin.com>

183
bin/server Executable file
View File

@@ -0,0 +1,183 @@
#!/usr/bin/env perl
# server - control Webmin web-server
use strict;
use warnings;
use 5.010;
use File::Basename;
use Getopt::Long;
use Pod::Usage;
use Term::ANSIColor qw(:constants);
use lib (dirname(dirname($0)));
use WebminCore;
sub main
{
my %opt;
GetOptions('help|h' => \$opt{'help'},
'command|x=s' => \$opt{'command'},
'config|c=s' => \$opt{'config'});
# If username passed as regular param
my $cmd = scalar(@ARGV) == 1 && $ARGV[0];
$cmd = $opt{'command'} if ($opt{'command'});
if ($cmd !~ /^(status|start|stop|restart|reload|force-restart|force-reload|kill)$/) {
$cmd = undef;
}
# Show usage
pod2usage(0) if ($opt{'help'} || !$cmd);
# Assign defaults
$opt{'config'} ||= "/etc/webmin";
$opt{'cmd'} = $cmd;
# Catch kill signal
my $sigkill = sub {
system("stty echo");
print "\n^C";
print "\n";
exit 1;
};
$SIG{INT} = \&$sigkill;
# Run change password command
run(\%opt);
return 0;
}
exit main(\@ARGV) if !caller(0);
sub run
{
my ($o) = @_;
my $conf_check = sub {
my ($configs) = @_;
foreach my $config (@{$configs}) {
if (!-r $config) {
say BRIGHT_RED, "Error: ", RESET, "Failed to read Webmin essential config file: ", BRIGHT_YELLOW, $config,
RESET, " doesn't exist";
exit 1;
}
}
};
root($o->{'config'}, \&$conf_check);
my $service = ($o->{'config'} =~ /usermin/ ? 'usermin' : 'webmin');
my $systemctlcmd = `which systemctl`;
$systemctlcmd =~ s/\s+$//;
if ($o->{'cmd'} =~ /^(start|stop|restart|reload)$/) {
my $rs = system("$o->{'config'}/$o->{'cmd'} $service");
exit $rs;
}
if ($o->{'cmd'} =~ /^(kill|force-kill)$/) {
my $rs;
if (-x $systemctlcmd) {
$rs = system("$systemctlcmd stop $service");
$rs = system("$systemctlcmd kill -s SIGTERM $service");
}
$rs = system("$o->{'config'}/.stop-init --kill >/dev/null 2>&1 $service");
exit $rs;
}
if ($o->{'cmd'} =~ /^(force-reload|force-restart)$/) {
my $rs = system("$o->{'config'}/restart-by-force-kill $service");
exit $rs;
}
if ($o->{'cmd'} =~ /^(status)$/) {
my $rs;
if (-x $systemctlcmd) {
$rs = system("$systemctlcmd status $service");
} else {
$rs = system("service $service status");
}
exit $rs;
}
exit 0;
}
sub root
{
my ($config, $conf_check) = @_;
my $mconf = "$config/miniserv.conf";
$conf_check->([$mconf]);
open(my $CONF, "<", $mconf);
my $root;
while (<$CONF>) {
if (/^root=(.*)/) {
$root = $1;
}
}
close($CONF);
# Does the Webmin root exist?
if ($root) {
die BRIGHT_RED, "Error: ", BRIGHT_YELLOW, $root, RESET, " is not a directory\n" unless (-d $root);
} else {
# Try to guess where Webmin lives, since config file didn't know.
die BRIGHT_RED, "Error: ", RESET, "Unable to determine Webmin installation directory\n";
}
return $root;
}
1;
=pod
=head1 NAME
server
=head1 DESCRIPTION
This program allows you to control Webmin web-server
=head1 SYNOPSIS
webmin server [command]
webmin [command]
=head1 OPTIONS
=over
=item --help, -h
Print this usage summary and exit.
Examples of usage:
- webmin server status
- webmin server restart
- webmin server --config /usr/local/etc/webmin --command start
- webmin status
- webmin restart
=item --config, -c
Specify the full path to the Webmin configuration directory. Defaults to C</etc/webmin>
=item --command, -x
Available commands:
- status
- start
- stop
- restart
- reload
- force-restart
- force-reload
- kill
Alias commands:
- force-restart | force-reload
- kill | force-kill
=back
=head1 LICENSE AND COPYRIGHT
Copyright 2022 Jamie Cameron <jcameron@webmin.com>
Joe Cooper <joe@virtualmin.com>
Ilia Rostovtsev <ilia@virtualmin.com>

View File

@@ -136,7 +136,7 @@ Set a configuration directive in either C<miniserv.conf> (the core Webmin config
=head1 SYNOPSIS
set-config [options] [--module] --option <option-name> --value <value>
webmin set-config [options] [--module] --option <option-name> --value <value>
=head1 OPTIONS
@@ -180,6 +180,5 @@ already exist in the file, and was added)
=head1 LICENSE AND COPYRIGHT
Copyright 2018 Jamie Cameron <jcameron@webmin.com>, Joe Cooper
<joe@virtualmin.com>.
Copyright 2022 Jamie Cameron <jcameron@webmin.com>
Joe Cooper <joe@virtualmin.com>

View File

@@ -12,6 +12,8 @@ use Term::ANSIColor qw(:constants);
use File::Spec;
use File::Basename;
my $a0 = $ARGV[0];
sub main {
my ( %opt, $subcmd );
GetOptions(
@@ -37,6 +39,7 @@ sub main {
);
$opt{'config'} ||= "/etc/webmin";
$opt{'commands'} = $a0;
my @remain = @ARGV;
# List commands?
@@ -203,7 +206,7 @@ sub run_command {
exit 1;
}
my $command_path = get_command_path($root, $subcmd);
my $command_path = get_command_path($root, $subcmd, $optref);
# Merge the options
# Only handling config, right now...
@@ -223,7 +226,7 @@ sub run_command {
}
sub get_command_path {
my ($root, $subcmd) = @_;
my ($root, $subcmd, $optref) = @_;
# Check for a root-level command (in "$root/bin")
my $command_path;
if ($subcmd) {
@@ -256,11 +259,13 @@ sub get_command_path {
}
}
}
if ($command) {
if ($optref->{'commands'} &&
$optref->{'commands'} =~ /^(status|start|stop|restart|reload|force-restart|force-reload|kill)$/) {
exit system("$0 server $optref->{'commands'}");
} elsif ($command) {
return $command;
} else {
die RED, "Unrecognized subcommand: $subcmd", RESET;
die RED, "Unrecognized subcommand: $subcmd", RESET , "\n";
}
}
@@ -325,7 +330,7 @@ sub man_command {
my ($optref, $subcmd) = @_;
my $root = root($optref->{'config'});
my $command_path = get_command_path($root, $subcmd);
my $command_path = get_command_path($root, $subcmd, $optref);
$ENV{'PAGER'} ||= "more";
open(my $PAGER, "|-", "$ENV{'PAGER'}");
@@ -341,7 +346,7 @@ sub man_command {
sub root {
my ($config) = @_;
open(my $CONF, "<", "$config/miniserv.conf") || die RED,
"Failed to open $config/miniserv.conf", RESET;
"Failed to open $config/miniserv.conf", RESET , "\n";
my $root;
while (<$CONF>) {
if (/^root=(.*)/) {
@@ -351,9 +356,9 @@ sub root {
close($CONF);
# Does the Webmin root exist?
if ( $root ) {
die "$root is not a directory. Is --config correct?" unless (-d $root);
die "$root is not a directory. Is --config correct?\n" unless (-d $root);
} else {
die "Unable to determine Webmin installation directory from $ENV{'WEBMIN_CONFIG'}";
die "Unable to determine Webmin installation directory from $ENV{'WEBMIN_CONFIG'}\n";
}
return $root;
@@ -412,14 +417,11 @@ Returns Webmin and other modules and themes versions installed (only those for w
=head1 EXIT CODES
0 on success
non-0 on error
0 on success ; non-0 on error
=head1 LICENSE AND COPYRIGHT
Copyright 2022
Jamie Cameron <jamie@virtualmin.com>,
Joe Cooper <joe@virtualmin.com>,
Ilia Rostovtsev <ilia@virtualmin.com>.
Copyright 2022 Jamie Cameron <jcameron@webmin.com>
Joe Cooper <joe@virtualmin.com>
Ilia Rostovtsev <ilia@virtualmin.com>

View File

@@ -0,0 +1,4 @@
dovecot=/usr/sbin/dovecot
dovecot_config=/etc/dovecot/dovecot.conf
init_script=dovecot.service
pid_file=/run/dovecot/master.pid

View File

@@ -0,0 +1,4 @@
dovecot=/usr/sbin/dovecot
dovecot_config=/etc/dovecot/dovecot.conf
init_script=dovecot.service
pid_file=/run/dovecot/master.pid

View File

@@ -13,7 +13,8 @@ my ($jail_list) = $out =~ /jail\s+list:\s*(.*)/im;
my @jails = split(/,\s*/, $jail_list);
if (@jails) {
my $tdc = 'style="text-align: center;"';
my $tal = 'style="text-align: left;"';
my $tal = 'style="text-align: right; font-size: 96%;"';
my $lwf = 'style="width: 100%; padding-right: 4px;"';
my @links = ( &select_all_link("jail"),
&select_invert_link("jail") );
my $head;
@@ -43,7 +44,7 @@ if (@jails) {
my $jips;
&open_execute_command($fh, $jcmd, 1);
while(<$fh>) {
if (/-\s+(.*):\s*(.*)/) {
if (/-\s+(.*?):\s*(.*)/) {
my $col = $1;
my $val = $2;
$col = lc($col);
@@ -53,9 +54,9 @@ if (@jails) {
if ($col =~ /banned_ip_list/) {
$jips = $val;
my @ips = split(/\s+/, $val);
@ips = map { "<small $tal><label>" . &ui_link("unblock_jail.cgi?unblock=1&jips-@{[&urlize($jail)]}=@{[&urlize($_)]}&jail=@{[&urlize($jail)]}", $_, undef,
@ips = map { "<small $tal><tt><label $lwf>" . &ui_link("unblock_jail.cgi?unblock=1&jips-@{[&urlize($jail)]}=@{[&urlize($_)]}&jail=@{[&urlize($jail)]}", $_, undef,
"title=\"@{[&text('status_jail_unblock_ip', &quote_escape($_))]}\" onmouseover=\"this.style.textDecoration='line-through'\" onmouseout=\"this.style.textDecoration='none'\""
) . "</label></small>" } @ips;
) . "</label></tt></small>" } @ips;
$val = "<br>" if ($val);
$val .= join('<br>', @ips);
$val = &$ipslimit($val);

View File

@@ -124,13 +124,18 @@ elsif ($init_mode eq "systemd") {
&enable_at_boot(
$product,
"$ucproduct server daemon",
"$config_directory/.start-init",
"$config_directory/.stop-init",
"$root_directory/miniserv.pl $config_directory/miniserv.conf",
'/usr/bin/kill $MAINPID',
undef,
{ 'pidfile' => $var_directory."/miniserv.pid",
'opts' => {
'type' => 'forking',
'killmode' => 'none'
{ 'pidfile' => "$var_directory/miniserv.pid",
'opts' => {
'env' => '"PERLLIB=' . $root_directory . '"',
'stop' => '/usr/bin/kill $MAINPID',
'reload' => '/bin/bash -c \'/usr/bin/kill -HUP $MAINPID && while /usr/bin/kill -0 $MAINPID >/dev/null 2>&1 ; do /bin/sleep 0.5 ; done\'',
'type' => 'forking',
'restart' => 'always',
'restartsec' => '2s',
'timeout' => '15s',
}},
);
}

View File

@@ -2343,6 +2343,8 @@ if (ref($opts)) {
&print_tempfile(CFILE, "Group=$opts->{'group'}\n") if ($opts->{'group'});
&print_tempfile(CFILE, "KillMode=$opts->{'killmode'}\n") if ($opts->{'killmode'});
&print_tempfile(CFILE, "WorkingDirectory=$opts->{'workdir'}\n") if ($opts->{'workdir'});
&print_tempfile(CFILE, "Restart=$opts->{'restart'}\n") if ($opts->{'restart'});
&print_tempfile(CFILE, "RestartSec=$opts->{'restartsec'}\n") if ($opts->{'restartsec'});
&print_tempfile(CFILE, "TimeoutSec=$opts->{'timeout'}\n") if ($opts->{'timeout'});
&print_tempfile(CFILE, "StandardOutput=file:$opts->{'logstd'}\n") if ($opts->{'logstd'});
&print_tempfile(CFILE, "StandardError=file:$opts->{'logerr'}\n") if ($opts->{'logerr'});
@@ -2425,6 +2427,23 @@ if (-d $systemd_unit_dir1) {
return $systemd_unit_dir2;
}
=head2 get_systemd_unit_pid([name])
Returns pid of running systemd unit
Returns 0 if unit stopped or missing
=cut
sub get_systemd_unit_pid
{
my ($unit) = @_;
my $pid =
&backquote_command("systemctl show --property MainPID @{[quotemeta($unit)]}");
$pid =~ s/MainPID=(\d+)/$1/;
$pid = int($pid);
return $pid;
}
=head2 restart_systemd()
Tell the systemd daemon to re-read its config

View File

@@ -24,7 +24,7 @@ if ($product) {
&copy_source_dest("$root_directory/webmin-systemd", "$temp");
my $lref = &read_file_lines($temp);
foreach my $l (@{$lref}) {
$l =~ s/(WEBMIN_[A-Z]+)/$ENV{$1}/;
$l =~ s/(WEBMIN_[A-Z]+)/$ENV{$1}/g;
}
&flush_file_lines($temp);
copy_source_dest($temp, "$systemd_root/$product.service");

View File

@@ -2533,7 +2533,7 @@ foreach my $f (@$folders) {
}
}
push(@opts, [ $byid ? &folder_name($f) : $f->{'index'},
$f->{'name'}.$umsg ]);
&html_escape($f->{'name'}).$umsg ]);
}
return &ui_select($name, $byid ? &folder_name($folder) : $folder->{'index'},
\@opts, 1, 0, 0, 0, $auto ? "onChange='form.submit()'" : "");

View File

@@ -57,6 +57,7 @@ else {
# Work out perl library path
$ENV{'PERLLIB'} = $wadir;
$ENV{'WEBMIN_LIBDIR'} = $wadir;
if ($ENV{'perllib'}) {
$ENV{'PERLLIB'} .= ":".$ENV{'perllib'};
}
@@ -649,7 +650,7 @@ else {
# Reload systemd
open(RELOADD, ">$config_directory/reload");
print RELOADD "$config_directory/.reload-init >/dev/null 2>&1\n";
print RELOADD "$systemctlcmd reload webmin\n";
close(RELOADD);
chmod(0755, "$config_directory/start");

View File

@@ -72,10 +72,12 @@ cd "$wadir"
# Work out perl library path
PERLLIB=$wadir
WEBMIN_LIBDIR=$wadir
if [ "$perllib" != "" ]; then
PERLLIB="$PERLLIB:$perllib"
fi
export PERLLIB
export WEBMIN_LIBDIR
# Validate source directory
allmods=`cd "$srcdir"; echo */module.info | sed -e 's/\/module.info//g'`
@@ -699,7 +701,7 @@ if [ -x "$systemctlcmd" ]; then
echo "$systemctlcmd start webmin" >>$config_dir/restart-by-force-kill
# Reload systemd
echo "#!/bin/sh" >>$config_dir/reload
echo "$config_dir/.reload-init >/dev/null 2>&1" >>$config_dir/reload
echo "$systemctlcmd reload webmin" >>$config_dir/reload
# Fix existing systemd webmin.service file to update start and stop commands
(cd "$wadir/init" ; WEBMIN_CONFIG=$config_dir WEBMIN_VAR=$var_dir "$wadir/init/updateboot.pl" "webmin")

View File

@@ -81,20 +81,13 @@ else {
&unlock_file($usermin_miniserv_config);
# Attempt to re-start miniserv
$SIG{'TERM'} = 'ignore';
&system_logged("$config{'usermin_dir'}/stop >/dev/null 2>&1 </dev/null");
$temp = &transname();
$rv = &system_logged("$config{'usermin_dir'}/start >$temp 2>&1 </dev/null");
$out = &read_file_contents($temp);
$out =~ s/^Starting Usermin server in.*\n//;
$out =~ s/at.*line.*//;
unlink($temp);
$rv = &system_logged("$config{'usermin_dir'}/restart >/dev/null 2>&1 </dev/null");
if ($rv) {
# Failed! Roll back config and start again
&lock_file($usermin_miniserv_config);
&put_usermin_miniserv_config(\%oldminiserv);
&unlock_file($usermin_miniserv_config);
&system_logged("$config{'usermin_dir'}/start >/dev/null 2>&1 </dev/null");
&system_logged("$config{'usermin_dir'}/restart >/dev/null 2>&1 </dev/null");
&error(&text('bind_erestart', $out));
}

View File

@@ -89,6 +89,7 @@ all configuration files.
sub restart_usermin_miniserv
{
return undef if (&is_readonly_mode());
return &miniserv_systemd_sig('HUP', 'usermin');
local($pid, %miniserv, $addr, $i);
&get_usermin_miniserv_config(\%miniserv) || return;
$miniserv{'inetd'} && return;

View File

@@ -2310,8 +2310,9 @@ it to restart. This will apply all configuration settings.
=cut
sub restart_miniserv
{
my ($nowait, $ignore) = @_;
return undef if (&is_readonly_mode());
return if (&miniserv_systemd_sig('HUP'));
my ($nowait, $ignore) = @_;
my %miniserv;
&get_miniserv_config(\%miniserv) || return;
if ($main::webmin_script_type eq 'web' && !$ENV{"MINISERV_CONFIG"} &&
@@ -2399,8 +2400,9 @@ IP addresses and ports to accept connections on.
=cut
sub reload_miniserv
{
my ($ignore) = @_;
return undef if (&is_readonly_mode());
return if (&miniserv_systemd_sig('USR1'));
my ($ignore) = @_;
my %miniserv;
&get_miniserv_config(\%miniserv) || return;
if ($main::webmin_script_type eq 'web' && !$ENV{"MINISERV_CONFIG"} &&
@@ -2452,6 +2454,41 @@ else {
}
}
=head2 miniserv_systemd_sig(signal, [product])
Uses systemd to send given signal to existing miniserv process.
Used to either fully restart it or just reload configuration
=cut
sub miniserv_systemd_sig
{
my ($sig, $product) = @_;
$sig =~ tr/A-Z0-9//cd;
if (&has_command('systemctl')) {
my $unit_target = $product || &get_product_name();
my ($upathr,
$upathd,
$ufile) =
("/usr/lib/systemd/system",
"/lib/systemd/system",
"$unit_target.service");
my $upathfile = -r "$upathr/$ufile" ? "$upathr/$ufile" :
-r "$upathd/$ufile" ? "$upathd/$ufile" : undef;
if ($upathfile) {
my $cmd = $sig eq 'HUP' ?
"systemctl reload" :
"systemctl kill -s SIG$sig";
my $rs = &system_logged("$cmd $unit_target");
if (!$rs) {
return 1;
}
}
return 0;
}
return 0;
}
=head2 check_os_support(&minfo, [os-type, os-version], [api-only])
Returns 1 if some module is supported on the current operating system, or the

View File

@@ -1,17 +1,16 @@
[Unit]
Description=Webmin server daemon
After=syslog.target
[Service]
ExecStart=WEBMIN_CONFIG/.start-init
ExecStop=WEBMIN_CONFIG/.stop-init
ExecReload=WEBMIN_CONFIG/.reload-init
Environment="PERLLIB=WEBMIN_LIBDIR"
ExecStart=WEBMIN_LIBDIR/miniserv.pl WEBMIN_CONFIG/miniserv.conf
ExecStop=/usr/bin/kill $MAINPID
ExecReload=/bin/bash -c '/usr/bin/kill -HUP $MAINPID && while /usr/bin/kill -0 $MAINPID >/dev/null 2>&1 ; do /bin/sleep 0.5 ; done'
PIDFile=WEBMIN_VAR/miniserv.pid
Type=forking
Restart=always
RestartSec=2s
OOMPolicy=kill
OOMScoreAdjust=-100
TimeoutSec=15s
[Install]
WantedBy=multi-user.target

View File

@@ -1788,6 +1788,10 @@ Output a page with header and footer about Webmin needing to restart.
=cut
sub show_restart_page
{
if (&miniserv_systemd_sig('HUP')) {
&redirect("");
return;
}
my ($title, $msg) = @_;
$title ||= $text{'restart_title'};
$msg ||= $text{'restart_done'};