Add ability for the master admin to send forgotten password reset links

This commit is contained in:
Jamie Cameron
2025-05-04 15:54:08 -07:00
parent d0f31831b6
commit ff742eddc1
5 changed files with 106 additions and 6 deletions

View File

@ -460,6 +460,9 @@ if ($in{'user'}) {
if ($access{'switch'} && $main::session_id && $in{'user'} ne $remote_user) {
push(@buts, [ "but_switch", $text{'edit_switch'} ]);
}
if ($user{'email'} && $gconfig{'forgot_pass'}) {
push(@buts, [ "but_forgot", $text{'edit_forgot'} ]);
}
if ($access{'delete'}) {
push(@buts, [ "but_delete", $text{'delete'} ]);
}

View File

@ -6,9 +6,33 @@ use warnings;
no warnings 'redefine';
no warnings 'uninitialized';
require './acl-lib.pl';
our (%in, %text, %config, %access, $base_remote_user);
our (%in, %text);
&foreign_require("webmin");
&error_setup($text{'forgot_err'});
&ReadParse();
&can_edit_user($in{'user'}) || &error($text{'edit_euser'});
my $u = &get_user($in{'user'});
$u || &error($text{'edit_egone'});
&ui_print_header(undef, $text{'forgot_title'}, "");
print $text{'forgot_desc'},"<p>\n";
print &ui_form_start("forgot_send.cgi", "post");
print &ui_hidden("user", $in{'user'});
print &ui_table_start($text{'forgot_header'}, undef, 2);
print &ui_table_row($text{'forgot_user'}, "<tt>$u->{'name'}</tt>");
print &ui_table_row($text{'forgot_email'},
&ui_textbox("email", $u->{'email'}, 60));
if ($u->{'name'} eq 'root') {
print &ui_table_row($text{'forgot_unix'},
&ui_opt_textbox("unix", undef, 20, $text{'forgot_unix_def'}));
}
print &ui_table_end();
print &ui_form_end([ [ undef, $text{'forgot_send'} ] ]);
&ui_print_footer("", $text{'index_return'});

57
acl/forgot_send.cgi Normal file
View File

@ -0,0 +1,57 @@
#!/usr/local/bin/perl
# Actually send the password reset email
use strict;
use warnings;
no warnings 'redefine';
no warnings 'uninitialized';
require './acl-lib.pl';
our (%in, %text);
&foreign_require("webmin");
&error_setup($text{'forgot_err'});
&ReadParse();
&can_edit_user($in{'user'}) || &error($text{'edit_euser'});
my $wuser = &get_user($in{'user'});
$wuser || &error($text{'edit_egone'});
# Validate inputs
$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'});
$unixuser = $in{'unix'};
}
# Generate a random ID and tracking file for this password reset
my $now = time();
my %link = ( 'id' => &generate_random_id(),
'remote' => $ENV{'REMOTE_ADDR'},
'time' => $now,
'user' => $wuser->{'name'},
'uuser' => $unixuser, );
$link{'id'} || &error($text{'forgot_erandom'});
&write_file("$main::forgot_password_link_dir/$link{'id'}", \%link);
my $baseurl = &get_webmin_email_url();
my $url = $baseurl.'/forgot.cgi?id='.&urlize($link{'id'});
$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";
my $username = $unixuser || $wuser->{'name'};
my $subject = &text('forgot_subject', $username);
&mailboxes::send_text_mail(&mailboxes::get_from_address(),
$in{'email'},
undef,
$subject,
$msg);
&webmin_log("forgot", "admin", undef,
{ 'user' => $unixuser || $wuser->{'name'},
'unix' => $unixuser ? 1 : 0,
'email' => $in{'email'} });
&redirect("");

View File

@ -91,6 +91,7 @@ edit_selall=Select all
edit_invert=Invert selection
edit_hide=Hide Unused
edit_switch=Switch to User
edit_forgot=Send Password Reset Link
edit_return=Webmin user
edit_return2=Webmin group
edit_rbacdeny=RBAC access mode
@ -514,4 +515,15 @@ twofactor_done=.. complete. Your ID with this provider is <tt>$1</tt>.
twofactor_setup=Two-factor authentication has not been enabled on this system yet, but can be turned on using the <a href='$1'>Webmin Configuration</a> module.
twofactor_ebutton=No button clicked!
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_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_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
__norefs=1

View File

@ -14,24 +14,28 @@ our (%in, %text, %config, %access, $config_directory, $base_remote_user);
# Check for special button clicks, and redirect
if ($in{'but_clone'}) {
&redirect("edit_user.cgi?clone=".&urlize($in{'old'}));
exit;
return;
}
elsif ($in{'but_log'}) {
&redirect("../webminlog/search.cgi?uall=0&mall=1&tall=1&user=".
&urlize($in{'old'}));
exit;
return;
}
elsif ($in{'but_switch'}) {
&redirect("switch.cgi?user=".&urlize($in{'old'}));
exit;
return;
}
elsif ($in{'but_delete'}) {
&redirect("delete_user.cgi?user=".&urlize($in{'old'}));
exit;
return;
}
elsif ($in{'twofactor'}) {
&redirect("twofactor_form.cgi?user=".&urlize($in{'old'}));
exit;
return;
}
elsif ($in{'but_forgot'}) {
&redirect("forgot_form.cgi?user=".&urlize($in{'old'}));
return;
}
# Get the user object