mirror of
https://github.com/webmin/webmin.git
synced 2026-03-20 08:40:24 +00:00
Add ability to force reset lost admin password for MySQL
This commit is contained in:
@@ -96,7 +96,7 @@ if ($r == 0) {
|
||||
elsif ($r == -1) {
|
||||
# Running, but webmin doesn't know the root (or user's) password!
|
||||
&main_header();
|
||||
print "<b>$text{'index_nopass'}</b> <p>\n";
|
||||
print "$text{'index_nopass'} <p>\n";
|
||||
|
||||
print &ui_form_start("login.cgi", "post");
|
||||
print &ui_table_start($text{'index_ltitle'}, undef, 2);
|
||||
@@ -105,7 +105,8 @@ elsif ($r == -1) {
|
||||
&ui_textbox("login", $access{'user'} || $config{'login'}, 40));
|
||||
|
||||
print &ui_table_row($text{'index_pass'},
|
||||
&ui_password("pass", undef, 40));
|
||||
&ui_password("pass", undef, 40) . "<br>" .
|
||||
&ui_checkbox("force", 1, $text{'mysqlpass_echange_forcepass'}));
|
||||
|
||||
print &ui_table_end();
|
||||
print &ui_form_end([ [ undef, $text{'save'} ] ]);
|
||||
|
||||
@@ -858,4 +858,13 @@ root_epass1=No new password entered
|
||||
root_epass2=Passwords do not match
|
||||
root_none=No password!
|
||||
root_auto=Automatic (typically <tt>root</tt>)
|
||||
|
||||
mysqlpass_err=MySQL safe mode
|
||||
mysqlpass_esafecmd=The command $1 needed to start MySQL with authentication disabled was not found
|
||||
mysqlpass_eshutdown=Shutdown failed : $1
|
||||
mysqlpass_esafe=Startup in safe mode failed : $1
|
||||
mysqlpass_estartup=Startup failed : $1
|
||||
mysqlpass_echange=Password change failed : $1
|
||||
mysqlpass_echange_forcepass=Force override the given password, if lost or forgotten
|
||||
|
||||
__norefs=1
|
||||
|
||||
@@ -9,6 +9,7 @@ $access{'user'} || !$access{'noconfig'} || &error($text{'login_ecannot'});
|
||||
$in{'login'} || &error($text{'login_elogin'});
|
||||
$mysql_login = $config{'login'} = $in{'login'};
|
||||
$mysql_pass = $config{'pass'} = $in{'pass'};
|
||||
$in{'force'} && force_set_mysql_admin_pass($mysql_login, $mysql_pass);
|
||||
$authstr = &make_authstr();
|
||||
if (&is_mysql_running() == -1) {
|
||||
&error($text{'login_epass'});
|
||||
|
||||
@@ -1764,5 +1764,109 @@ if (defined($c->{'pass'})) {
|
||||
&start_mysql();
|
||||
}
|
||||
|
||||
# force_set_mysql_admin_pass(user, pass)
|
||||
# Forcibly change MySQL admin password, if lost or forgotten
|
||||
sub force_set_mysql_admin_pass
|
||||
{
|
||||
my ($user, $pass) = @_;
|
||||
&error_setup($text{'mysqlpass_err'});
|
||||
&foreign_require("proc");
|
||||
|
||||
# Find the mysqld_safe command
|
||||
my $safe = &has_command("mysqld_safe");
|
||||
if (!$safe) {
|
||||
&error(&text('mysqlpass_esafecmd', "<tt>mysqld_safe</tt>"));
|
||||
}
|
||||
|
||||
# Shut down server if running
|
||||
if (&is_mysql_running()) {
|
||||
my $err = &stop_mysql();
|
||||
if ($err) {
|
||||
&error(&text('mysqlpass_esafecmdeshutdown', $err));
|
||||
}
|
||||
}
|
||||
|
||||
# Start up with skip-grants flag
|
||||
my $cmd = $safe." --skip-grant-tables";
|
||||
|
||||
# Running with `mysqld_safe` - when called, command doesn't create "mysqld" directory under
|
||||
# "/var/run" eventually resulting in DBI connect failed error on all MySQL versions
|
||||
my $ver = &get_mysql_version();
|
||||
if ($ver !~ /mariadb/i) {
|
||||
my $mysockdir = '/var/run/mysqld';
|
||||
my $myusergrp = 'mysql';
|
||||
my $myconf = &get_mysql_config();
|
||||
if ($myconf) {
|
||||
my ($mysqld) = grep { $_->{'name'} eq 'mysqld' } @$myconf;
|
||||
if ($mysqld) {
|
||||
my $members = $mysqld->{'members'};
|
||||
|
||||
# Look for user
|
||||
my $myusergrp_ = &find_value("user", $members);
|
||||
if ($myusergrp_) {
|
||||
$myusergrp = $myusergrp_;
|
||||
}
|
||||
|
||||
# Look for socket
|
||||
my $mysockdir_ = &find_value("socket", $members);
|
||||
if ($mysockdir_) {
|
||||
$mysockdir = $mysockdir_;
|
||||
$mysockdir =~ s/^(.+)\/([^\/]+)$/$1/;
|
||||
}
|
||||
}
|
||||
}
|
||||
$cmd = "mkdir -p $mysockdir && chown $myusergrp:$myusergrp $mysockdir && $cmd";
|
||||
}
|
||||
my ($pty, $pid) = &proc::pty_process_exec($cmd, 0, 0);
|
||||
sleep(5);
|
||||
if (!$pid || !kill(0, $pid)) {
|
||||
my $err = <$pty>;
|
||||
&error(&text('mysqlpass_esafe', $err));
|
||||
}
|
||||
|
||||
# Update password by running command directly
|
||||
my $cmd = $config{'mysql'} || 'mysql';
|
||||
my $sql = &get_change_pass_sql($pass, $user, 'localhost');
|
||||
my $out = &backquote_command("$cmd -D $master_db -e ".
|
||||
quotemeta("flush privileges; $sql")." 2>&1 </dev/null");
|
||||
if ($?) {
|
||||
$out =~ s/\n/ /gm;
|
||||
&error(&text('mysqlpass_echange', "$out"));
|
||||
}
|
||||
else {
|
||||
|
||||
# Update root password now for other
|
||||
# hosts, using regular database connection
|
||||
my $d = &execute_sql_safe($master_db,
|
||||
"select host from user where user = ?", $user);
|
||||
@hosts = map { $_->[0] ne 'localhost' } @{$d->{'data'}};
|
||||
foreach my $host (@hosts) {
|
||||
$sql = get_change_pass_sql($pass, $user, $host);
|
||||
eval {
|
||||
local $main::error_must_die = 1;
|
||||
&execute_sql_logged($master_db, 'flush privileges');
|
||||
&execute_sql_logged($master_db, $sql);
|
||||
&execute_sql_logged($master_db, 'flush privileges');
|
||||
sleep 1;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
# Shut down again, with the mysqladmin command
|
||||
my $mysql_shutdown = $config{'mysqladmin'} || 'mysqladmin';
|
||||
my $out = &backquote_logged("$mysql_shutdown shutdown 2>&1 </dev/null");
|
||||
if ($?) {
|
||||
$out =~ s/\n/ /gm;
|
||||
&error(&text('mysqlpass_eshutdown', $out));
|
||||
}
|
||||
|
||||
# Finally, re-start in normal mode
|
||||
my $err = &start_mysql();
|
||||
if ($err) {
|
||||
&error(&text('mysqlpass_estartup', $err));
|
||||
}
|
||||
&error_setup($text{'login_err'});
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user