mirror of
https://github.com/webmin/webmin.git
synced 2026-05-04 14:20:31 +01:00
Completed password change lockout function
This commit is contained in:
@@ -25,6 +25,11 @@ print &ui_table_row($text{'pass_maxdays'},
|
||||
&ui_opt_textbox("maxdays", $miniserv{'pass_maxdays'}, 5,
|
||||
$text{'pass_nomaxdays'})." ".$text{'pass_days'});
|
||||
|
||||
# Days before lockout
|
||||
print &ui_table_row($text{'pass_lockdays'},
|
||||
&ui_opt_textbox("lockdays", $miniserv{'pass_lockdays'}, 5,
|
||||
$text{'pass_nolockdays'})." ".$text{'pass_days'});
|
||||
|
||||
# Disallow use of username
|
||||
print &ui_table_row($text{'pass_nouser'},
|
||||
&ui_yesno_radio("nouser", $miniserv{'pass_nouser'}));
|
||||
|
||||
@@ -338,6 +338,7 @@ pass_minsize=Minimum password length
|
||||
pass_nominsize=No minimum
|
||||
pass_regexps=Regular expressions passwords must match
|
||||
pass_maxdays=Days before password must be changed
|
||||
pass_lockdays=Days before un-changed password locks account
|
||||
pass_nomaxdays=Change never required
|
||||
pass_nouser=Disallow passwords containing username?
|
||||
pass_nodict=Disallow dictionary word passwords?
|
||||
@@ -348,6 +349,7 @@ pass_pass=passwords
|
||||
pass_err=Failed to save password restrictions
|
||||
pass_eminsize=Missing or non-numeric minimum password length
|
||||
pass_emaxdays=Missing or non-numeric number of days before changing
|
||||
pass_elockdays=Missing or non-numeric number of days before account is locked
|
||||
pass_eoldblock=Missing or non-numeric number of old passwords to reject
|
||||
|
||||
cpass_minsize=Must be at least $1 letters long
|
||||
|
||||
@@ -22,6 +22,13 @@ else {
|
||||
$in{'maxdays'} =~ /^\d+$/ || &error($text{'pass_emaxdays'});
|
||||
$miniserv{'pass_maxdays'} = $in{'maxdays'};
|
||||
}
|
||||
if ($in{'lockdays_def'}) {
|
||||
delete($miniserv{'pass_lockdays'});
|
||||
}
|
||||
else {
|
||||
$in{'lockdays'} =~ /^\d+$/ || &error($text{'pass_elockdays'});
|
||||
$miniserv{'pass_lockdays'} = $in{'lockdays'};
|
||||
}
|
||||
$miniserv{'pass_nouser'} = $in{'nouser'};
|
||||
$miniserv{'pass_nodict'} = $in{'nodict'};
|
||||
if ($in{'oldblock_def'}) {
|
||||
|
||||
25
miniserv.pl
25
miniserv.pl
@@ -2899,8 +2899,27 @@ elsif ($canmode == 0) {
|
||||
}
|
||||
elsif ($canmode == 1) {
|
||||
# Attempt Webmin authentication
|
||||
return $users{$webminuser} eq &unix_crypt($pass, $users{$webminuser}) ?
|
||||
( $user, 0, 0 ) : ( undef, 0, 0 );
|
||||
if ($users{$webminuser} eq &unix_crypt($pass, $users{$webminuser})) {
|
||||
# Password is valid .. but check for expiry
|
||||
local $lc = $lastchanges{$user};
|
||||
if ($config{'pass_maxdays'} && $lc) {
|
||||
local $daysold = (time() - $lc)/(24*60*60);
|
||||
print DEBUG "maxdays=$config{'pass_maxdays'} daysold=$daysold\n";
|
||||
if ($config{'pass_lockdays'} &&
|
||||
$daysold > $config{'pass_lockdays'}) {
|
||||
# So old that the account is locked
|
||||
return ( undef, 0, 0 );
|
||||
}
|
||||
elsif ($daysold > $config{'pass_maxdays'}) {
|
||||
# Password has expired
|
||||
return ( $user, 1, 0 );
|
||||
}
|
||||
}
|
||||
return ( $user, 0, 0 );
|
||||
}
|
||||
else {
|
||||
return ( undef, 0, 0 );
|
||||
}
|
||||
}
|
||||
elsif ($canmode == 2 || $canmode == 3) {
|
||||
# Attempt PAM or passwd file authentication
|
||||
@@ -3842,6 +3861,7 @@ undef(%allow);
|
||||
undef(%deny);
|
||||
undef(%allowdays);
|
||||
undef(%allowhours);
|
||||
undef(%lastchanges);
|
||||
if ($config{'userfile'}) {
|
||||
open(USERS, $config{'userfile'});
|
||||
while(<USERS>) {
|
||||
@@ -3865,6 +3885,7 @@ if ($config{'userfile'}) {
|
||||
if ($user[5] =~ /hours\s+(\d+)\.(\d+)-(\d+).(\d+)/) {
|
||||
$allowhours{$user[0]} = [ $1*60+$2, $3*60+$4 ];
|
||||
}
|
||||
$lastchanges{$user[0]} = $user[6];
|
||||
}
|
||||
close(USERS);
|
||||
}
|
||||
|
||||
@@ -8,16 +8,41 @@ require './web-lib.pl';
|
||||
&ReadParse();
|
||||
&get_miniserv_config(\%miniserv);
|
||||
$miniserv{'passwd_mode'} == 2 || die "Password changing is not enabled!";
|
||||
if (!$in{'pam'}) {
|
||||
$miniserv{'passwd_cindex'} ne '' && $miniserv{'passwd_mindex'} ne '' ||
|
||||
die "Missing password file configuration";
|
||||
}
|
||||
|
||||
# Validate inputs
|
||||
$in{'new1'} ne '' || &pass_error($text{'password_enew1'});
|
||||
$in{'new1'} eq $in{'new2'} || &pass_error($text{'password_enew2'});
|
||||
|
||||
if ($in{'pam'}) {
|
||||
# Is this a Webmin user?
|
||||
if (&foreign_check("acl")) {
|
||||
&foreign_require("acl", "acl-lib.pl");
|
||||
($wuser) = grep { $_->{'name'} eq $in{'user'} } &acl::list_users();
|
||||
if ($wuser->{'pass'} eq 'x') {
|
||||
# A Webmin user, but using Unix authentication
|
||||
$wuser = undef;
|
||||
}
|
||||
elsif ($wuser->{'pass'} eq '*LK*' ||
|
||||
$wuser->{'pass'} =~ /^\!/) {
|
||||
&pass_error("Webmin users with locked accounts cannot change ".
|
||||
"their passwords!");
|
||||
}
|
||||
}
|
||||
if (!$in{'pam'} && !$wuser) {
|
||||
$miniserv{'passwd_cindex'} ne '' && $miniserv{'passwd_mindex'} ne '' ||
|
||||
die "Missing password file configuration";
|
||||
}
|
||||
|
||||
if ($wuser) {
|
||||
# Update Webmin user's password
|
||||
$enc = &acl::encrypt_password($in{'old'}, $wuser->{'pass'});
|
||||
$enc eq $wuser->{'pass'} || &pass_error($text{'password_eold'});
|
||||
$perr = &acl::check_password_restrictions($in{'user'}, $in{'new1'});
|
||||
$perr && &pass_error(&text('password_enewpass', $perr));
|
||||
$wuser->{'pass'} = &acl::encrypt_password($in{'new1'});
|
||||
&acl::modify_user($wuser->{'name'}, $wuser);
|
||||
&reload_miniserv();
|
||||
}
|
||||
elsif ($in{'pam'}) {
|
||||
# Use PAM to make the change..
|
||||
eval "use Authen::PAM;";
|
||||
if ($@) {
|
||||
|
||||
Reference in New Issue
Block a user