mirror of
https://github.com/webmin/webmin.git
synced 2026-02-03 14:13:29 +00:00
Merge branch 'master' of github.com:webmin/webmin
This commit is contained in:
229
bin/passwd
Executable file
229
bin/passwd
Executable file
@@ -0,0 +1,229 @@
|
||||
#!/usr/bin/env perl
|
||||
# passwd - change Webmin users password
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use 5.010;
|
||||
|
||||
use Getopt::Long;
|
||||
use Pod::Usage;
|
||||
use Term::ANSIColor qw(:constants);
|
||||
|
||||
sub main
|
||||
{
|
||||
my %opt;
|
||||
GetOptions('help|h' => \$opt{'help'},
|
||||
'config|c=s' => \$opt{'config'},
|
||||
'user|u=s' => \$opt{'user'},
|
||||
'password|p=s' => \$opt{'password'});
|
||||
pod2usage(0) if ($opt{'help'} || !$opt{'user'});
|
||||
|
||||
$opt{'config'} ||= "/etc/webmin";
|
||||
$opt{'password'} ||= "";
|
||||
|
||||
my $sigkill = sub {
|
||||
system("stty echo");
|
||||
print "\n^C";
|
||||
print "\n";
|
||||
exit 1;
|
||||
};
|
||||
$SIG{INT} = \&$sigkill;
|
||||
|
||||
change_password(\%opt);
|
||||
|
||||
return 0;
|
||||
}
|
||||
exit main(\@ARGV) if !caller(0);
|
||||
|
||||
sub change_password
|
||||
{
|
||||
my ($optref) = @_;
|
||||
my ($minserv_uconf_file, %lusers, @users, %uinfos, %ulines);
|
||||
my $user = "$optref->{'user'}";
|
||||
my $pass = "$optref->{'password'}";
|
||||
my $confdif = $optref->{'config'};
|
||||
my $conf = "$confdif/config";
|
||||
my $mconf = "$confdif/miniserv.conf";
|
||||
my $encrypt_password = sub {
|
||||
my ($pass, $gconfig) = @_;
|
||||
if ($gconfig->{'md5pass'} == 1) {
|
||||
|
||||
# Use MD5 encryption
|
||||
return &encrypt_md5($pass);
|
||||
} elsif ($gconfig->{'md5pass'} == 2) {
|
||||
|
||||
# Use SHA512 encryption
|
||||
return &encrypt_sha512($pass);
|
||||
} else {
|
||||
|
||||
# Use Unix DES
|
||||
srand(time() ^ $$);
|
||||
return crypt($pass, chr(int(rand(26)) + 65) . chr(int(rand(26)) + 65));
|
||||
}
|
||||
};
|
||||
my $conf_check = sub {
|
||||
my ($configs) = @_;
|
||||
foreach my $config (@{$configs}) {
|
||||
if (!-r $config) {
|
||||
say BRIGHT_RED, "Error: ", RESET, "Failed to read Webmin essential config file: ", BRIGHT_YELLOW, $config,
|
||||
RESET, " doesn't exist";
|
||||
exit 1;
|
||||
}
|
||||
}
|
||||
};
|
||||
my $root = root($confdif, \&$conf_check);
|
||||
|
||||
# Load libs
|
||||
do "$root/acl/md5-lib.pl";
|
||||
do "$root/web-lib-funcs.pl";
|
||||
|
||||
# Check for main config and miniserv config files
|
||||
&$conf_check([$conf, $mconf]);
|
||||
|
||||
# Read and parse configs
|
||||
my (%config, %gconfig, %uconfig);
|
||||
read_file($mconf, \%config);
|
||||
read_file($conf, \%gconfig);
|
||||
$minserv_uconf_file = $config{'userfile'};
|
||||
|
||||
# Check for main user file
|
||||
&$conf_check([$minserv_uconf_file]);
|
||||
|
||||
read_file($minserv_uconf_file, \%lusers, undef, undef, ":");
|
||||
@users = keys %lusers;
|
||||
map {my @uinfo = split(':', "$lusers{$_}"); $uinfos{$_} = \@uinfo} @users;
|
||||
|
||||
# Chech if user exists
|
||||
if (!defined($uinfos{$user})) {
|
||||
my $user_str = scalar(@users) > 1 ? 'users' : 'user';
|
||||
my $user_str2 = scalar(@users) > 1 ? 'are' : 'is';
|
||||
die(BRIGHT_RED, "Error: ", RESET . "Webmin user ",
|
||||
BRIGHT_YELLOW, $user, RESET, " doesn't exist. Existing Webmin $user_str on your system $user_str2 — ",
|
||||
BRIGHT_YELLOW, join(", ", sort(@users)),
|
||||
RESET, "\n");
|
||||
}
|
||||
|
||||
# Ask for password on stdin
|
||||
my $suc_pre_msg = GREEN . 'Success:' . RESET;
|
||||
my $suc_msg = 'updated successfully';
|
||||
if (!$pass) {
|
||||
print "Enter password for user ", BRIGHT_YELLOW, $user, RESET, ":";
|
||||
system("stty -echo");
|
||||
$pass = <STDIN>;
|
||||
system("stty echo");
|
||||
print "\nRetype new password:";
|
||||
system("stty -echo");
|
||||
my $pass2 = <STDIN>;
|
||||
system("stty echo");
|
||||
print "\n";
|
||||
|
||||
if ($pass ne $pass2) {
|
||||
say BRIGHT_RED, "Error: ", RESET, "Passwords do not match";
|
||||
exit 1;
|
||||
}
|
||||
chomp $pass;
|
||||
if (!$pass) {
|
||||
$suc_pre_msg = YELLOW . 'Warning:' . RESET;
|
||||
$suc_msg = "has been removed";
|
||||
}
|
||||
}
|
||||
|
||||
# Update with new password and store timestamp
|
||||
$uinfos{$user}->[0] = &$encrypt_password($pass, \%gconfig);
|
||||
$uinfos{$user}->[5] = time() if ($uinfos{$user}->[5]);
|
||||
map {$ulines{$_} = join(":", @{ $uinfos{$_} })} keys %uinfos;
|
||||
|
||||
# Store original file first
|
||||
copy_source_dest($minserv_uconf_file, "$minserv_uconf_file-");
|
||||
|
||||
# Restart Webmin and write new user config file
|
||||
system("$confdif/stop >/dev/null 2>&1");
|
||||
write_file($minserv_uconf_file, \%ulines, ":");
|
||||
system("$confdif/start >/dev/null 2>&1");
|
||||
|
||||
# Print user message
|
||||
say "$suc_pre_msg Password for Webmin user ", BRIGHT_YELLOW, $user, RESET, " $suc_msg";
|
||||
|
||||
exit 0;
|
||||
}
|
||||
|
||||
sub root
|
||||
{
|
||||
my ($config, $conf_check) = @_;
|
||||
my $mconf = "$config/miniserv.conf";
|
||||
$conf_check->([$mconf]);
|
||||
open(my $CONF, "<", $mconf);
|
||||
my $root;
|
||||
while (<$CONF>) {
|
||||
if (/^root=(.*)/) {
|
||||
$root = $1;
|
||||
}
|
||||
}
|
||||
close($CONF);
|
||||
|
||||
# Does the Webmin root exist?
|
||||
if ($root) {
|
||||
die BRIGHT_RED, "Error: ", BRIGHT_YELLOW, $root, RESET, " is not a directory\n" unless (-d $root);
|
||||
} else {
|
||||
|
||||
# Try to guess where Webmin lives, since config file didn't know.
|
||||
die BRIGHT_RED, "Error: ", RESET, "Unable to determine Webmin installation directory\n";
|
||||
}
|
||||
|
||||
return $root;
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
=pod
|
||||
|
||||
=head1 NAME
|
||||
|
||||
passwd
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
This program allows you to change the password of a user in the Webmin password file
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
passwd [options]
|
||||
|
||||
=head1 OPTIONS
|
||||
|
||||
=over
|
||||
|
||||
=item --help, -h
|
||||
|
||||
Print this usage summary and exit.
|
||||
|
||||
Examples of usage:
|
||||
|
||||
- passwd --user root
|
||||
|
||||
- passwd --user root --password ycwyMQRVAZY
|
||||
|
||||
- passwd --config /usr/local/etc/webmin --user root --password ycwyMQRVAZY
|
||||
|
||||
=item --config, -c
|
||||
|
||||
Specify the full path to the Webmin configuration directory. Defaults to C</etc/webmin>
|
||||
|
||||
=item --user, -u
|
||||
|
||||
Existing Webmin user to change password for
|
||||
|
||||
=item --password, -p
|
||||
|
||||
Set new user password. Using this option may be unsecure.
|
||||
|
||||
|
||||
|
||||
=back
|
||||
|
||||
=head1 LICENSE AND COPYRIGHT
|
||||
|
||||
Copyright 2021 Jamie Cameron <jcameron@webmin.com>
|
||||
Joe Cooper <joe@virtualmin.com>
|
||||
Ilia Rostovtsev <ilia@virtualmin.com>
|
||||
|
||||
Reference in New Issue
Block a user