mirror of
				https://github.com/xcat2/xcat-core.git
				synced 2025-10-31 03:12:30 +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:
		| @@ -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. | ||||
|   | ||||
|  | ||||
|  | ||||
|   | ||||
| @@ -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.", | ||||
|   | ||||
| @@ -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; | ||||
| } | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
| @@ -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); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user