diff --git a/forgot.cgi b/forgot.cgi index a8f926e94..4136e58a2 100755 --- a/forgot.cgi +++ b/forgot.cgi @@ -26,9 +26,33 @@ time() - $link{'time'} > 60*$timeout && # Get the Webmin user &foreign_require("acl"); my ($wuser) = grep { $_->{'name'} eq $link{'user'} } &acl::list_users(); -$wuser || &error(&text('forgot_euser2', + +# 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"); + foreach my $d (&virtual_server::list_domains()) { + my @users = + &virtual_server::list_domain_users($d, 0, 0, 0, 0, 1); + ($muser) = grep { $_->{'user'} eq lc($link{'muser'}) } @users; + if ($muser) { + $muserdom = $d; + last; + } + } + } + +# Show an error if neither user was found +!$muser && $link{'muser'} && &error(&text('forgot_euser3', + "".&html_escape($link{'muser'})."")); +$wuser || $muser || &error(&text('forgot_euser2', "".&html_escape($link{'user'})."")); -my $username = $link{'uuser'} || $link{'user'}; + +# 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; &ui_print_header(undef, $text{'forgot_title'}, "", undef, undef, 1, 1); @@ -86,6 +110,17 @@ if (defined($in{'newpass'})) { &virtual_server::pop_all_print(); print $text{'forgot_done'},"

\n"; } + 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); + } elsif ($link{'uuser'} || $wuser->{'pass'} eq 'x') { # Update in Users and Groups print &text('forgot_udoing', @@ -116,12 +151,20 @@ if (defined($in{'newpass'})) { &reload_miniserv(); print $text{'forgot_done'},"

\n"; } - print &text('forgot_retry', '/'),"

\n"; + + # Print link to login for Webmin user + if (!$muser) { + print &text('forgot_retry', &get_webprefix()."/", + "".$username.""),"

\n"; + } + else { + print &text('forgot_retry2', "".$username.""),"

\n"; + } &webmin_log("forgot", "reset", undef, { 'user' => $username, 'unix' => $link{'uuser'} ? 1 : 0, - 'email' => $wuser->{'email'} }, "acl"); + 'email' => $email }, "acl"); &unlink_logged($linkfile); } diff --git a/forgot_send.cgi b/forgot_send.cgi index bd6f78cdd..f60aa54ef 100755 --- a/forgot_send.cgi +++ b/forgot_send.cgi @@ -27,7 +27,22 @@ if (!$wuser) { ($wuser) = grep { $_->{'name'} eq 'root' } &acl::list_users(); } } -my $email = $wuser ? $wuser->{'email'} : undef; + +# If no Webmin user, then try to get mail user from Virtualmin +my $muser; +if (!$wuser && &foreign_check("virtual-server")) { + # Probably in Virtualmin, so try to find the user + &foreign_require("virtual-server"); + foreach my $d (&virtual_server::list_domains()) { + my @users = + &virtual_server::list_domain_users($d, 0, 0, 0, 0, 1); + ($muser) = grep { $_->{'user'} eq lc($in{'forgot'}) } @users; + last if ($muser); + } + } + +my $email = $wuser ? $wuser->{'email'} : + $muser ? $muser->{'recovery'} || $muser->{'email'} : undef; # Check if the IP or Webmin user is over it's rate limit &make_dir($main::forgot_password_link_dir, 0700); @@ -43,6 +58,7 @@ my $ptime = $gconfig{'passreset_time'} // 60; foreach my $key ($ENV{'REMOTE_ADDR'}, $wuser ? ( $wuser->{'name'} ) : ( ), $uuser ? ( $uuser->{'user'} ) : ( ), + $muser ? ( $muser->{'user'} ) : ( ), $email ? ( $email ) : ( )) { # Don't block if disabled next if (!$pfailures || !$ptime); @@ -83,7 +99,7 @@ sleep($maxtries); &error($rlerr) if ($rlerr); # Make sure the Webmin user exists and is eligible for a reset -$wuser && $wuser->{'email'} || &error($text{'forgot_euser'}); +(($wuser && $email) || ($muser && $email)) || &error($text{'forgot_euser'}); ($wuser->{'sync'} || $wuser->{'pass'} eq 'e') && &error($text{'forgot_esync'}); $wuser->{'pass'} eq '*LK*' && &error($text{'forgot_elock'}); @@ -92,7 +108,8 @@ my %link = ( 'id' => &acl::generate_random_id(), 'remote' => $ENV{'REMOTE_ADDR'}, 'time' => $now, 'user' => $wuser->{'name'}, - 'uuser' => $uuser ? $uuser->{'user'} : undef, ); + 'uuser' => $uuser ? $uuser->{'user'} : undef, + 'muser' => $muser ? $muser->{'user'} : undef, ); $link{'id'} || &error($text{'forgot_erandom'}); my $linkfile = $main::forgot_password_link_dir."/".$link{'id'}; &lock_file($linkfile); @@ -100,8 +117,9 @@ my $linkfile = $main::forgot_password_link_dir."/".$link{'id'}; &unlock_file($linkfile); my $baseurl = &get_webmin_email_url(); my $url = $baseurl.'/forgot.cgi?id='.&urlize($link{'id'}); -my $username = $uuser ? $uuser->{'user'} : $wuser->{'name'}; -$url = &theme_forgot_url($baseurl, $link{'id'}, $link{'user'}) +my $username = $muser ? $muser->{'user'} : + $uuser ? $uuser->{'user'} : $wuser->{'name'}; +$url = &theme_forgot_url($baseurl, $link{'id'}, $username) if (defined(&theme_forgot_url)); &ui_print_header(undef, $text{'forgot_title'}, "", undef, undef, 1, 1); @@ -128,6 +146,6 @@ print "\n"; &webmin_log("forgot", "send", undef, { 'user' => $username, - 'unix' => $uuser ? 1 : 0, + 'unix' => $muser || $uuser ? 1 : 0, 'email' => $email }, "acl"); &ui_print_footer(); diff --git a/lang/en b/lang/en index 2b7d85a0f..287a3cfd7 100644 --- a/lang/en +++ b/lang/en @@ -147,31 +147,33 @@ session_save=Remember login permanently? session_forgot=Forgot Password? forgot_title=Reset Forgotten Password -forgot_user=Webmin username: -forgot_desc=If your Webmin login has a recovery email address associated with it, you can use this page to send a link that can be used to reset the password. +forgot_user=Username: +forgot_desc=If your account has a recovery email set, you can use this form to send yourself a password reset link. forgot_go=Send Password Reset Link forgot_ecannot=Forgotten password recovery is not enabled! -forgot_euser=The username either does not exist or does not have a recovery email configured. -forgot_msg=You are receiving this email due to a request for password recovery from the Webmin system at $4 from $3, for the login $1.\n\nIf you would like to proceed with resetting the password, follow this link :\n$2 -forgot_subject=Webmin password reset for $1 -forgot_sent=A link to reset your Webmin password for login $2 has been sent to the recovery email address $1. +forgot_euser=The user either does not exist or does not have a recovery email configured. +forgot_msg=You are receiving this email due to a request for password recovery from the Webmin system at $4 from $3, for the username $1.\n\nIf you would like to proceed with resetting the password, follow this link:\n$2 +forgot_subject=Password reset for user $1 +forgot_sent=A link to reset your password for user $2 has been sent to the recovery email address $1. forgot_erandom=Failed to generate random ID! forgot_eid=Missing or invalid-looking reset ID! forgot_eid2=Reset ID is not valid! forgot_etime=Password reset email is more than $1 minutes old. -forgot_newpass=New password for Webmin user $1 +forgot_newpass=New password for user $1 forgot_newpass2=New password again forgot_passok=Change Password forgot_euser2=Webmin user $1 does not exist! +forgot_euser3=Mailbox user $1 does not exist! forgot_esync=The password cannot be changed for this user forgot_elock=The password for this user is locked forgot_err=Failed to reset password forgot_enewpass=No new password entered! forgot_enewpass2=New passwords do not match! forgot_equality=Password requirements were not met : $1 -forgot_wdoing=Changing password for Webmin user $1 .. +forgot_wdoing=Changing password for user $1 .. forgot_done=.. password change complete. -forgot_retry=You can now login to Webmin using your new password. +forgot_retry=The password for Webmin user $2 was reset successfully. You can now log in using your new password. +forgot_retry2=The password for mailbox user $1 was reset successfully. forgot_edisabled=The password for a disabled Virtualmin domain cannot be reset forgot_vdoing=Changing password for Virtualmin domain $1 .. forgot_udoing=Changing password for Unix user $1 ..