update-users-groups.pl: Generate hashed passwords internally
I.e. don't call "passwd" to update /etc/shadow from the "password" option. This has the side-effect of not updating the password if mutableUsers = true (since the code path for "hashedPassword" has a check for mutableUsers). Fixes #4747.
This commit is contained in:
parent
919ed14477
commit
a9f5e77e2f
@ -6,6 +6,15 @@ use JSON;
|
|||||||
make_path("/var/lib/nixos", { mode => 0755 });
|
make_path("/var/lib/nixos", { mode => 0755 });
|
||||||
|
|
||||||
|
|
||||||
|
sub hashPassword {
|
||||||
|
my ($password) = @_;
|
||||||
|
my $salt = "";
|
||||||
|
my @chars = ('.', '/', 0..9, 'A'..'Z', 'a'..'z');
|
||||||
|
$salt .= $chars[rand 64] for (1..8);
|
||||||
|
return crypt($password, '$6$' . $salt . '$');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
# Functions for allocating free GIDs/UIDs. FIXME: respect ID ranges in
|
# Functions for allocating free GIDs/UIDs. FIXME: respect ID ranges in
|
||||||
# /etc/login.defs.
|
# /etc/login.defs.
|
||||||
sub allocId {
|
sub allocId {
|
||||||
@ -174,6 +183,8 @@ foreach my $u (@{$spec->{users}}) {
|
|||||||
} else {
|
} else {
|
||||||
warn "warning: password file ‘$u->{passwordFile}’ does not exist\n";
|
warn "warning: password file ‘$u->{passwordFile}’ does not exist\n";
|
||||||
}
|
}
|
||||||
|
} elsif (defined $u->{password}) {
|
||||||
|
$u->{hashedPassword} = hashPassword($u->{password});
|
||||||
}
|
}
|
||||||
|
|
||||||
$u->{fakePassword} = $existing->{fakePassword} // "x";
|
$u->{fakePassword} = $existing->{fakePassword} // "x";
|
||||||
@ -208,32 +219,21 @@ my %shadowSeen;
|
|||||||
|
|
||||||
foreach my $line (-f "/etc/shadow" ? read_file("/etc/shadow") : ()) {
|
foreach my $line (-f "/etc/shadow" ? read_file("/etc/shadow") : ()) {
|
||||||
chomp $line;
|
chomp $line;
|
||||||
my ($name, $password, @rest) = split(':', $line, -9);
|
my ($name, $hashedPassword, @rest) = split(':', $line, -9);
|
||||||
my $u = $usersOut{$name};;
|
my $u = $usersOut{$name};;
|
||||||
next if !defined $u;
|
next if !defined $u;
|
||||||
$password = $u->{hashedPassword} if defined $u->{hashedPassword} && !$spec->{mutableUsers}; # FIXME
|
$hashedPassword = $u->{hashedPassword} if defined $u->{hashedPassword} && !$spec->{mutableUsers}; # FIXME
|
||||||
push @shadowNew, join(":", $name, $password, @rest) . "\n";
|
push @shadowNew, join(":", $name, $hashedPassword, @rest) . "\n";
|
||||||
$shadowSeen{$name} = 1;
|
$shadowSeen{$name} = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach my $u (values %usersOut) {
|
foreach my $u (values %usersOut) {
|
||||||
next if defined $shadowSeen{$u->{name}};
|
next if defined $shadowSeen{$u->{name}};
|
||||||
my $password = "!";
|
my $hashedPassword = "!";
|
||||||
$password = $u->{hashedPassword} if defined $u->{hashedPassword};
|
$hashedPassword = $u->{hashedPassword} if defined $u->{hashedPassword};
|
||||||
# FIXME: set correct value for sp_lstchg.
|
# FIXME: set correct value for sp_lstchg.
|
||||||
push @shadowNew, join(":", $u->{name}, $password, "1::::::") . "\n";
|
push @shadowNew, join(":", $u->{name}, $hashedPassword, "1::::::") . "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
write_file("/etc/shadow.tmp", { perms => 0600 }, @shadowNew);
|
write_file("/etc/shadow.tmp", { perms => 0600 }, @shadowNew);
|
||||||
rename("/etc/shadow.tmp", "/etc/shadow") or die;
|
rename("/etc/shadow.tmp", "/etc/shadow") or die;
|
||||||
|
|
||||||
|
|
||||||
# Call chpasswd to apply password. FIXME: generate the hashes directly
|
|
||||||
# and merge into the /etc/shadow updating above.
|
|
||||||
foreach my $u (@{$spec->{users}}) {
|
|
||||||
if (defined $u->{password}) {
|
|
||||||
my $pid = open(PW, "| chpasswd") or die;
|
|
||||||
print PW "$u->{name}:$u->{password}\n";
|
|
||||||
close PW or die "unable to change password of user ‘$u->{name}’: $?\n";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user