From 22946b82dea8b85ca30d9d87ee3d1b7f294bafed Mon Sep 17 00:00:00 2001 From: Jamie Cameron Date: Mon, 5 May 2025 22:01:56 -0700 Subject: [PATCH] Add option to show password reset link in the browser --- acl/forgot_form.cgi | 4 ++- acl/forgot_send.cgi | 60 +++++++++++++++++++++++++++++++-------------- acl/lang/en | 10 ++++++-- 3 files changed, 52 insertions(+), 22 deletions(-) mode change 100644 => 100755 acl/forgot_form.cgi diff --git a/acl/forgot_form.cgi b/acl/forgot_form.cgi old mode 100644 new mode 100755 index 62e1a842f..f2ea942be --- a/acl/forgot_form.cgi +++ b/acl/forgot_form.cgi @@ -25,7 +25,9 @@ print &ui_table_start($text{'forgot_header'}, undef, 2); print &ui_table_row($text{'forgot_user'}, "$u->{'name'}"); print &ui_table_row($text{'forgot_email'}, - &ui_textbox("email", $u->{'email'}, 60)); + &ui_opt_textbox("email", $u->{'email'}, 60, + $text{'forgot_email_def'}."
\n", + $text{'forgot_email_sel'})); if ($u->{'name'} eq 'root') { print &ui_table_row($text{'forgot_unix'}, diff --git a/acl/forgot_send.cgi b/acl/forgot_send.cgi index 8b3d0015b..d7e312555 100755 --- a/acl/forgot_send.cgi +++ b/acl/forgot_send.cgi @@ -6,7 +6,7 @@ use warnings; no warnings 'redefine'; no warnings 'uninitialized'; require './acl-lib.pl'; -our (%in, %text); +our (%in, %text, %gconfig); &foreign_require("webmin"); &error_setup($text{'forgot_err'}); &ReadParse(); @@ -15,7 +15,8 @@ my $wuser = &get_user($in{'user'}); $wuser || &error($text{'edit_egone'}); # Validate inputs -$in{'email'} =~ /^\S+\@\S+$/ || &error($text{'forgot_eemail'}); +$in{'email_def'} || $in{'email'} =~ /^\S+\@\S+$/ || + &error($text{'forgot_eemail'}); my $unixuser; if (defined($in{'unix_def'}) && !$in{'unix_def'}) { getpwnam($in{'unix'}) || &error($text{'forgot_eunix'}); @@ -31,29 +32,50 @@ my %link = ( 'id' => &generate_random_id(), 'uuser' => $unixuser, ); $link{'id'} || &error($text{'forgot_erandom'}); &make_dir($main::forgot_password_link_dir, 0700); -&write_file("$main::forgot_password_link_dir/$link{'id'}", \%link); +my $linkfile = $main::forgot_password_link_dir."/".$link{'id'}; +&lock_file($linkfile); +&write_file($linkfile, \%link); +&unlock_file($linkfile); my $baseurl = &get_webmin_email_url(); my $url = $baseurl.'/forgot.cgi?id='.&urlize($link{'id'}); &load_theme_library(); $url = &theme_forgot_url($baseurl, $link{'id'}, $link{'user'}) if (defined(&theme_forgot_url)); -# Construct and send the email -&foreign_require("mailboxes"); -my $msg = &text('forgot_adminmsg', $wuser->{'name'}, $url, $baseurl); -$msg =~ s/\\n/\n/g; -$msg = join("\n", &mailboxes::wrap_lines($msg, 75))."\n"; +&ui_print_header(undef, $text{'forgot_title'}, ""); + my $username = $unixuser || $wuser->{'name'}; -my $subject = &text('forgot_subject', $username); -&mailboxes::send_text_mail(&mailboxes::get_from_address(), - $in{'email'}, - undef, - $subject, - $msg); +if ($in{'email_def'}) { + # Just show the link + my $timeout = $gconfig{'passreset_timeout'} || 15; + print "

",&text('forgot_link', $username, $timeout),"

\n"; -&webmin_log("forgot", "admin", undef, - { 'user' => $unixuser || $wuser->{'name'}, - 'unix' => $unixuser ? 1 : 0, - 'email' => $in{'email'} }); -&redirect(""); + print "

".$url."

\n"; + &webmin_log("forgot", "link", undef, + { 'user' => $username, + 'unix' => $unixuser ? 1 : 0 }); + } +else { + # Construct and send the email + &foreign_require("mailboxes"); + my $msg = &text('forgot_adminmsg', $wuser->{'name'}, $url, $baseurl); + $msg =~ s/\\n/\n/g; + $msg = join("\n", &mailboxes::wrap_lines($msg, 75))."\n"; + my $subject = &text('forgot_subject', $username); + print &text('forgot_sending', + &html_escape($in{'email'}), $username),"
\n"; + &mailboxes::send_text_mail(&mailboxes::get_from_address(), + $in{'email'}, + undef, + $subject, + $msg); + print $text{'forgot_sent'},"

\n"; + + &webmin_log("forgot", "admin", undef, + { 'user' => $username, + 'unix' => $unixuser ? 1 : 0, + 'email' => $in{'email'} }); + } + +&ui_print_footer("", $text{'index_return'}); diff --git a/acl/lang/en b/acl/lang/en index 0db7ce256..249957951 100644 --- a/acl/lang/en +++ b/acl/lang/en @@ -252,6 +252,7 @@ log_twofactor=Enrolled user $1 with two-factor provider $2 log_onefactor=Dis-enrolled user $1 for two-factor authentication log_forgot_send=Sent password reset email for user $1 to $2 log_forgot_reset=Reset password for user $1 with email $2 +log_forgot_admin=Admin sent password reset email for user $1 to $2 gedit_ecannot=You are not allowed to edit groups gedit_title=Edit Webmin Group @@ -519,11 +520,16 @@ forgot_title=Send Password Reset Link forgot_err=Failed to send password reset link forgot_header=Password reset link details forgot_user=Reset password for Webmin user -forgot_email=Send link to email address +forgot_email=Link delivery method +forgot_email_def=Display link in Webmin +forgot_email_sel=Send link via email to forgot_unix=Sudo-capable Unix user to reset forgot_unix_def=Just reset Webmin password forgot_send=Send Link -forgot_desc=This page allows you to send a link that can be used to select a new password for a Webmin user to any email address. Be careful which address you send this link to, as it will effectively grant full access to the Webmin login! +forgot_desc=This page allows you to generate or send a link that can be used to select a new password for a Webmin user to any email address. Be careful which address you send this link to, as it will effectively grant full access to the Webmin login! forgot_adminmsg=You are receiving this email from the administrator of the Webmin system at $3, for the login $1.\n\nIf you would like to proceed with resetting the password, follow this link :\n$2 +forgot_sending=Sending password reset email for $2 to $1 .. +forgot_sent=.. sent! +forgot_link=The link below can be used to reset the Webmin password for $1 for the next $2 minutes : __norefs=1