2025-04-14 22:44:55 -07:00
|
|
|
#!/usr/local/bin/perl
|
|
|
|
# Linked to from the forgotten password email
|
|
|
|
|
|
|
|
BEGIN { push(@INC, "."); };
|
|
|
|
use WebminCore;
|
|
|
|
$no_acl_check++;
|
2025-04-15 21:23:10 -07:00
|
|
|
$trust_unknown_referers = 1;
|
2025-04-14 22:44:55 -07:00
|
|
|
&init_config();
|
|
|
|
&ReadParse();
|
2025-04-25 20:01:30 +03:00
|
|
|
&load_theme_library();
|
|
|
|
|
2025-05-21 22:02:02 +03:00
|
|
|
&theme_forgot_handler($0) if (defined(&theme_forgot_handler));
|
2025-04-25 20:01:30 +03:00
|
|
|
&error_setup($text{'forgot_err'});
|
2025-04-14 22:44:55 -07:00
|
|
|
$gconfig{'forgot_pass'} || &error($text{'forgot_ecannot'});
|
2025-05-03 20:49:04 -07:00
|
|
|
my $timeout = $gconfig{'passreset_timeout'} || 15;
|
2025-04-20 10:30:14 -07:00
|
|
|
$remote_user && &error($text{'forgot_elogin'});
|
2025-04-14 22:44:55 -07:00
|
|
|
|
|
|
|
# Check that the random ID is valid
|
|
|
|
$in{'id'} =~ /^[a-f0-9]+$/i || &error($text{'forgot_eid'});
|
|
|
|
my %link;
|
2025-05-05 20:08:12 -07:00
|
|
|
my $linkfile = $main::forgot_password_link_dir."/".$in{'id'};
|
|
|
|
&read_file($linkfile, \%link) || &error($text{'forgot_eid2'});
|
2025-05-03 20:49:04 -07:00
|
|
|
time() - $link{'time'} > 60*$timeout &&
|
|
|
|
&error(&text('forgot_etime', $timeout));
|
2025-04-14 22:44:55 -07:00
|
|
|
|
|
|
|
# Get the Webmin user
|
|
|
|
&foreign_require("acl");
|
|
|
|
my ($wuser) = grep { $_->{'name'} eq $link{'user'} } &acl::list_users();
|
2025-05-31 23:40:39 +03:00
|
|
|
|
|
|
|
# Get the Virtualmin mail Unix user if Webmin user is not found
|
|
|
|
my ($muser, $muserdom);
|
|
|
|
if (!$wuser && $link{'muser'}) {
|
|
|
|
# Probably Virtualmin mail user, so try to find it
|
|
|
|
&foreign_require("virtual-server");
|
2025-06-01 10:24:05 +03:00
|
|
|
my $d = &virtual_server::get_user_domain(lc($link{'muser'}));
|
|
|
|
if ($d) {
|
|
|
|
my @u = &virtual_server::list_domain_users($d, 0, 0, 1, 1, 0);
|
|
|
|
($muser) = grep { $_->{'user'} eq lc($link{'muser'}) } @u;
|
2025-05-31 23:40:39 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
# Show an error if neither user was found
|
|
|
|
!$muser && $link{'muser'} && &error(&text('forgot_euser3',
|
|
|
|
"<tt>".&html_escape($link{'muser'})."</tt>"));
|
|
|
|
$wuser || $muser || &error(&text('forgot_euser2',
|
2025-04-14 22:44:55 -07:00
|
|
|
"<tt>".&html_escape($link{'user'})."</tt>"));
|
2025-05-31 23:40:39 +03:00
|
|
|
|
|
|
|
# Set the username whichever is available
|
|
|
|
my $username = $link{'muser'} || $link{'uuser'} || $link{'user'};
|
|
|
|
my $email = $wuser ? $wuser->{'email'} :
|
|
|
|
$muser ? $muser->{'recovery'} || $muser->{'email'} : undef;
|
2025-04-14 22:44:55 -07:00
|
|
|
|
|
|
|
&ui_print_header(undef, $text{'forgot_title'}, "", undef, undef, 1, 1);
|
|
|
|
|
|
|
|
if (defined($in{'newpass'})) {
|
|
|
|
# Validate the password
|
|
|
|
$in{'newpass'} =~ /\S/ || &error($text{'forgot_enewpass'});
|
2025-04-21 19:56:20 -07:00
|
|
|
$in{'newpass'} eq $in{'newpass2'} ||
|
|
|
|
&error($text{'forgot_enewpass2'});
|
2025-04-14 22:44:55 -07:00
|
|
|
my $perr = &acl::check_password_restrictions(
|
|
|
|
$wuser->{'name'}, $in{'newpass'});
|
|
|
|
$perr && &error(&text('forgot_equality', $perr));
|
|
|
|
|
|
|
|
# Actually update the password
|
2025-04-22 22:01:21 -07:00
|
|
|
my $d;
|
2025-04-14 22:44:55 -07:00
|
|
|
if (&foreign_check("virtual-server")) {
|
|
|
|
# Is this a Virtualmin domain owner?
|
|
|
|
&foreign_require("virtual-server");
|
|
|
|
$d = &virtual_server::get_domain_by("user", $link{'user'},
|
|
|
|
"parent", "");
|
2025-04-23 20:51:59 -07:00
|
|
|
$d && $d->{'disabled'} && &error($text{'forgot_edisabled'});
|
2025-04-14 22:44:55 -07:00
|
|
|
}
|
2025-04-23 20:51:59 -07:00
|
|
|
if ($d) {
|
2025-04-14 22:44:55 -07:00
|
|
|
# Update in Virtualmin
|
2025-04-17 22:11:39 -07:00
|
|
|
print &text('forgot_vdoing',
|
|
|
|
&virtual_server::show_domain_name($d)),"<br>\n";
|
2025-04-21 16:55:35 -07:00
|
|
|
&virtual_server::push_all_print();
|
|
|
|
&virtual_server::set_all_null_print();
|
2025-04-17 22:11:39 -07:00
|
|
|
foreach my $d (&virtual_server::get_domain_by("user", $link{'user'})) {
|
|
|
|
&virtual_server::lock_domain($d);
|
|
|
|
my $oldd = { %$d };
|
|
|
|
$d->{'pass'} = $in{'newpass'};
|
|
|
|
$d->{'pass_set'} = 1;
|
|
|
|
&virtual_server::generate_domain_password_hashes($d, 0);
|
|
|
|
|
|
|
|
# Update all features
|
|
|
|
foreach my $f (&virtual_server::domain_features($d)) {
|
|
|
|
if ($virtual_server::config{$f} && $d->{$f}) {
|
2025-05-19 21:56:11 -07:00
|
|
|
my $mfunc = "virtual_server::modify_$f";
|
2025-04-17 22:11:39 -07:00
|
|
|
&$mfunc($d, $oldd);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
# Update all plugins
|
|
|
|
foreach my $f (&virtual_server::list_feature_plugins()) {
|
|
|
|
if ($d->{$f}) {
|
|
|
|
&virtual_server::plugin_call(
|
|
|
|
$f, "feature_modify", $d, $oldd);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
&virtual_server::save_domain($d);
|
|
|
|
&virtual_server::unlock_domain($d);
|
|
|
|
}
|
2025-04-21 16:55:35 -07:00
|
|
|
&virtual_server::run_post_actions();
|
|
|
|
&virtual_server::pop_all_print();
|
2025-04-17 22:11:39 -07:00
|
|
|
print $text{'forgot_done'},"<p>\n";
|
2025-04-14 22:44:55 -07:00
|
|
|
}
|
2025-05-31 23:40:39 +03:00
|
|
|
elsif ($muser) {
|
|
|
|
# Update in Virtualmin if this is a mail user
|
|
|
|
my %oldmuser = %$muser;
|
|
|
|
$muser->{'plainpass'} = $in{'newpass'};
|
|
|
|
$muser->{'pass'} =
|
|
|
|
&virtual_server::encrypt_user_password(
|
|
|
|
$muser, $muser->{'plainpass'});
|
|
|
|
$muser->{'passmode'} = 3;
|
|
|
|
&virtual_server::set_pass_change($muser);
|
|
|
|
&virtual_server::modify_user($muser, \%oldmuser, $muserdom);
|
|
|
|
}
|
2025-05-03 22:05:46 -07:00
|
|
|
elsif ($link{'uuser'} || $wuser->{'pass'} eq 'x') {
|
2025-04-14 22:44:55 -07:00
|
|
|
# Update in Users and Groups
|
2025-04-18 22:01:56 -07:00
|
|
|
print &text('forgot_udoing',
|
2025-05-04 11:40:58 -07:00
|
|
|
"<tt>".&html_escape($username)."</tt>"),"<br>\n";
|
2025-04-18 22:01:56 -07:00
|
|
|
&foreign_require("useradmin");
|
2025-05-04 11:40:58 -07:00
|
|
|
my ($user) = grep { $_->{'user'} eq $username }
|
2025-04-23 20:56:21 -07:00
|
|
|
&useradmin::list_users();
|
|
|
|
$user || &error($text{'forgot_eunix'});
|
|
|
|
$user->{'pass'} eq $useradmin::config{'lock_string'} &&
|
2025-04-18 22:01:56 -07:00
|
|
|
&error($text{'forgot_eunixlock'});
|
2025-04-23 20:56:21 -07:00
|
|
|
my $olduser = { %$user };
|
2025-04-18 22:01:56 -07:00
|
|
|
$user->{'passmode'} = 3;
|
|
|
|
$user->{'plainpass'} = $in{'newpass'};
|
2025-04-23 15:18:09 +03:00
|
|
|
$user->{'pass'} = &useradmin::encrypt_password($in{'newpass'},
|
|
|
|
undef, 1);
|
2025-04-18 22:01:56 -07:00
|
|
|
&useradmin::modify_user($olduser, $user);
|
2025-04-23 15:18:09 +03:00
|
|
|
&useradmin::other_modules("useradmin_modify_user", $user,
|
|
|
|
$olduser);
|
|
|
|
&reload_miniserv();
|
2025-04-18 22:01:56 -07:00
|
|
|
print $text{'forgot_done'},"<p>\n";
|
2025-04-14 22:44:55 -07:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
# Update in Webmin
|
2025-04-15 21:23:10 -07:00
|
|
|
print &text('forgot_wdoing',
|
|
|
|
"<tt>".&html_escape($link{'user'})."</tt>"),"<br>\n";
|
2025-04-23 20:58:48 -07:00
|
|
|
$wuser->{'pass'} = &acl::encrypt_password($in{'newpass'});
|
2025-04-15 21:23:10 -07:00
|
|
|
&acl::modify_user($wuser->{'name'}, $wuser);
|
2025-04-14 22:44:55 -07:00
|
|
|
&reload_miniserv();
|
2025-04-15 21:23:10 -07:00
|
|
|
print $text{'forgot_done'},"<p>\n";
|
2025-04-14 22:44:55 -07:00
|
|
|
}
|
2025-06-01 02:07:41 +03:00
|
|
|
|
|
|
|
# Print link to login for Webmin user
|
|
|
|
if (!$muser) {
|
|
|
|
print &text('forgot_retry', &get_webprefix()."/",
|
|
|
|
"<tt>".$username."</tt>"),"<p>\n";
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
print &text('forgot_retry2', "<tt>".$username."</tt>"),"<p>\n";
|
|
|
|
}
|
2025-04-15 21:23:10 -07:00
|
|
|
|
2025-04-26 10:04:43 -07:00
|
|
|
&webmin_log("forgot", "reset", undef,
|
2025-05-04 11:40:58 -07:00
|
|
|
{ 'user' => $username,
|
|
|
|
'unix' => $link{'uuser'} ? 1 : 0,
|
2025-05-31 23:40:39 +03:00
|
|
|
'email' => $email }, "acl");
|
2025-04-26 10:04:43 -07:00
|
|
|
|
2025-05-05 20:08:12 -07:00
|
|
|
&unlink_logged($linkfile);
|
2025-04-14 22:44:55 -07:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
# Show password selection form
|
2025-04-15 21:23:10 -07:00
|
|
|
print "<center>\n";
|
2025-04-14 22:44:55 -07:00
|
|
|
print &ui_form_start("forgot.cgi", "post");
|
|
|
|
print &ui_hidden("id", $in{'id'});
|
2025-04-21 19:56:20 -07:00
|
|
|
print &ui_table_start(undef, undef, 2);
|
|
|
|
print &ui_table_row(
|
|
|
|
&text('forgot_newpass',
|
2025-05-04 11:40:58 -07:00
|
|
|
"<tt>".&html_escape($username)."</tt>"),
|
2025-04-21 19:56:20 -07:00
|
|
|
&ui_password("newpass", undef, 30));
|
|
|
|
print &ui_table_row(
|
|
|
|
$text{'forgot_newpass2'},
|
|
|
|
&ui_password("newpass2", undef, 30));
|
|
|
|
print &ui_table_end();
|
2025-04-14 22:44:55 -07:00
|
|
|
print &ui_form_end([ [ undef, $text{'forgot_passok'} ] ]);
|
2025-04-15 21:23:10 -07:00
|
|
|
print "</center>\n";
|
2025-04-14 22:44:55 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
&ui_print_footer();
|