2
0
mirror of https://github.com/xcat2/xcat-core.git synced 2025-05-29 09:13:08 +00:00

Merge pull request #2168 from chenglch/cryptmethod

Load the cryptmethod in the passwd table to generate the password
This commit is contained in:
yangsong 2016-11-22 00:14:17 -06:00 committed by GitHub
commit 223b3305ef
6 changed files with 109 additions and 72 deletions

View File

@ -56,7 +56,7 @@ passwd Attributes:
\ **cryptmethod**\
Indicates the method that was used to encrypt the password attribute. On AIX systems, if a value is provided for this attribute it indicates that the password attribute is encrypted. If the cryptmethod value is not set it indicates the password is a simple string value. On Linux systems, the cryptmethod is not supported however the code attempts to auto-discover MD5 encrypted passwords.
Indicates the method that was used to encrypt the password attribute. On AIX systems, if a value is provided for this attribute it indicates that the password attribute is encrypted. If the cryptmethod value is not set it indicates the password is a simple string value. On Linux systems, the cryptmethod can be set to md5, sha256 or sha512. If not set, sha256 will be used as default.

View File

@ -824,7 +824,7 @@ passed as argument rather than by table value',
key => 'The type of component this user/pw is for. Valid values: blade (management module), ipmi (BMC), system (nodes), omapi (DHCP), hmc, ivm, cec, frame, switch.',
username => 'The default userid for this type of component',
password => 'The default password for this type of component',
cryptmethod => 'Indicates the method that was used to encrypt the password attribute. On AIX systems, if a value is provided for this attribute it indicates that the password attribute is encrypted. If the cryptmethod value is not set it indicates the password is a simple string value. On Linux systems, the cryptmethod is not supported however the code attempts to auto-discover MD5 encrypted passwords.',
cryptmethod => 'Indicates the method that was used to encrypt the password attribute. On AIX systems, if a value is provided for this attribute it indicates that the password attribute is encrypted. If the cryptmethod value is not set it indicates the password is a simple string value. On Linux systems, the cryptmethod can be set to md5, sha256 or sha512. If not set, sha256 will be used as default.',
authdomain => 'The domain in which this entry has meaning, e.g. specifying different domain administrators per active directory domain',
comments => 'Any user-written notes.',
disable => "Set to 'yes' or '1' to comment out this row.",

View File

@ -1,9 +1,14 @@
package xCAT::PasswordUtils;
use xCAT::Table;
use xCAT::MsgUtils;
use xCAT::Utils;
my $ipmiuser = "USERID"; # default username to apply if nothing specified
my $ipmipass = "PASSW0RD"; # default password to apply if nothing specified
my $bladeuser = "USERID"; # default username to apply if nothing specified
my $bladepass = "PASSW0RD"; # default password to apply if nothing specified
my %CRYPT_METHOD = ('md5' => '$1$', 'sha256' => '$5$', 'sha512' => '$6$');
# Picks the IPMI authentication to use with or deploy to a BMC
# mandatory arguments:
@ -112,3 +117,48 @@ sub getIPMIAuth {
return \%authmap;
}
# Encrypt system password based on the values in passwd table
# The values for system root user will be used if query key-pair is not defined
sub crypt_system_password {
# Just leave these arguments here for the compability reasons in Template.pm
# which get these values by parsing the template files.
my ($table, $kp, $fields) = @_;
if (!defined($table)) {
$table = 'passwd';
}
if (!defined($kp)) {
$kp->{'key'} = 'system';
$kp->{username} = 'root';
$fields->[0] = 'password';
$fields->[1] = 'cryptmethod';
}
my $tabh = xCAT::Table->new($table);
unless ($tabh) {
return undef;
}
$data = $tabh->getAttribs($kp, @{$fields});
if (!defined($data)) {
xCAT::MsgUtils->message("S",
"ERROR: Unable to get data from database table $table, key=$key");
return undef;
}
$tabh->close();
$password = $data->{'password'};
if (!defined($password)) {
xCAT::MsgUtils->message("S",
"ERROR: Unable to get password from database table $table, key=$key");
return undef;
}
$cryptmethod = $data->{'cryptmethod'};
if (!$cryptmethod) {
# Use sha256 crypt method by default
$result = crypt($password, $CRYPT_METHOD{'sha256'} . xCAT::Utils::genpassword(8));
} elsif( defined($CRYPT_METHOD{$cryptmethod})) {
$result = crypt($password,
$CRYPT_METHOD{$cryptmethod} . xCAT::Utils::genpassword(8));
} else {
xCAT::MsgUtils->message("S", "Unsupported crypt method $cryptmethod");
return undef;
}
return $result;
}

View File

@ -15,6 +15,7 @@ use xCAT::ADUtils; #to allow setting of one-time machine passwords
use xCAT::Utils;
use xCAT::TableUtils;
use xCAT::NetworkUtils;
use xCAT::PasswordUtils;
use XML::Simple;
BEGIN
@ -1573,28 +1574,27 @@ sub envvar
return ($ENV{$envvar});
}
sub genpassword {
#Generate a pseudo-random password of specified length
my $length = shift;
my $password = '';
my $characters = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890';
srand; #have to reseed, rand is not rand otherwise
while (length($password) < $length) {
$password .= substr($characters, int(rand 63), 1);
}
return $password;
}
sub crydb
{
my $result = tabdb(@_);
my ($table, $key, $field) = @_;
my @fields = [$field, 'cryptmethod'];
my $kp;
# 1 - MD5, 5 - SHA256, 6 - SHA512
unless (($result =~ /^\$1\$/) || ($result =~ /^\$5\$/) || ($result =~ /^\$6\$/)) {
$result = crypt($result, '$1$' . genpassword(8));
}
return $result;
my $get_query_map = sub {
my $key = shift;
my %kp;
foreach (split /,/, $key) {
my ($k, $v);
($k, $v) = split /=/, $_;
$kp{$k} = $v if defined($k);
}
return \%kp if %kp;
sendmsg([ 1, "Unable to parse password parameters $key" ]);
return undef;
};
$kp = $get_query_map->($key);
return undef if (!defined($kp));
return xCAT::PasswordUtils::crypt_system_password($table, $kp, \@fields);
}
sub tabdb

View File

@ -37,6 +37,7 @@ use File::Path;
use xCAT::Utils;
use xCAT::TableUtils;
use xCAT::SvrUtils;
use xCAT::PasswordUtils;
use Digest::MD5 qw(md5_hex);
Getopt::Long::Configure("bundling");
@ -390,34 +391,27 @@ sub process_request {
# before packaging the image
system("umount $rootimg_dir/proc");
copybootscript($installroot, $rootimg_dir, $osver, $arch, $profile, $callback);
my $passtab = xCAT::Table->new('passwd');
if ($passtab) {
my $pass = 'cluster';
(my $pent) = $passtab->getAttribs({ key => 'system', username => 'root' }, 'password');
if ($pent and defined($pent->{password})) {
$pass = $pent->{password};
}
my $oldmask = umask(0077);
my $shadow;
open($shadow, "<", "$rootimg_dir/etc/shadow");
my @shadents = <$shadow>;
close($shadow);
open($shadow, ">", "$rootimg_dir/etc/shadow");
# 1 - MD5, 5 - SHA256, 6 - SHA512
unless (($pass =~ /^\$1\$/) || ($pass =~ /^\$5\$/) || ($pass =~ /^\$6\$/)) {
$pass = crypt($pass, '$1$' . xCAT::Utils::genpassword(8));
}
print $shadow "root:$pass:13880:0:99999:7:::\n";
foreach (@shadents) {
unless (/^root:/) {
print $shadow "$_";
}
}
close($shadow);
umask($oldmask);
my $pass = xCAT::PasswordUtils::crypt_system_password();
if (!defined($pass)) {
$pass = 'cluster';
}
my $oldmask = umask(0077);
my $shadow;
open($shadow, "<", "$rootimg_dir/etc/shadow");
my @shadents = <$shadow>;
close($shadow);
open($shadow, ">", "$rootimg_dir/etc/shadow");
print $shadow "root:$pass:13880:0:99999:7:::\n";
foreach (@shadents) {
unless (/^root:/) {
print $shadow "$_";
}
}
close($shadow);
umask($oldmask);
# sync fils configured in the synclist to the rootimage
$syncfile = xCAT::SvrUtils->getsynclistfile(undef, $osver, $arch, $profile, "netboot", $imagename);
if (defined($syncfile) && -f $syncfile

View File

@ -16,6 +16,7 @@ use File::Temp;
use xCAT::Utils qw(genpassword);
use xCAT::TableUtils qw(get_site_attribute);
use xCAT::SvrUtils;
use xCAT::PasswordUtils;
use Data::Dumper;
Getopt::Long::Configure("bundling");
Getopt::Long::Configure("pass_through");
@ -182,34 +183,26 @@ sub process_request {
#get the root password for the node
my $passtab = xCAT::Table->new('passwd');
if ($passtab) {
my $pass = 'cluster';
(my $pent) = $passtab->getAttribs({ key => 'system', username => 'root' }, 'password');
if ($pent and defined($pent->{password})) {
$pass = $pent->{password};
}
my $oldmask = umask(0077);
my $shadow;
open($shadow, "<", "$rootimg_dir/etc/shadow");
my @shadents = <$shadow>;
close($shadow);
open($shadow, ">", "$rootimg_dir/etc/shadow");
# 1 - MD5, 5 - SHA256, 6 - SHA512
unless (($pass =~ /^\$1\$/) || ($pass =~ /^\$5\$/) || ($pass =~ /^\$6\$/)) {
$pass = crypt($pass, '$1$' . genpassword(8));
}
print $shadow "root:$pass:13880:0:99999:7:::\n";
foreach (@shadents) {
unless (/^root:/) {
print $shadow "$_";
}
}
close($shadow);
umask($oldmask);
my $pass = xCAT::PasswordUtils::crypt_system_password();
if (!defined($pass)) {
$pass = 'cluster';
}
my $oldmask = umask(0077);
my $shadow;
open($shadow, "<", "$rootimg_dir/etc/shadow");
my @shadents = <$shadow>;
close($shadow);
open($shadow, ">", "$rootimg_dir/etc/shadow");
print $shadow "root:$pass:13880:0:99999:7:::\n";
foreach (@shadents) {
unless (/^root:/) {
print $shadow "$_";
}
}
close($shadow);
umask($oldmask);
my $distname = $osver;
unless (-r "$::XCATROOT/share/xcat/netboot/$distname/" or not $distname) {
chop($distname);