Merge pull request #98544 from Mic92/unfuck-update-user-group
nixos/update-user-groups: Fix encoding issues + atomic writes
This commit is contained in:
commit
75d7828724
1 changed files with 8 additions and 10 deletions
|
@ -16,8 +16,7 @@ my $gidMap = -e $gidMapFile ? decode_json(read_file($gidMapFile)) : {};
|
||||||
|
|
||||||
sub updateFile {
|
sub updateFile {
|
||||||
my ($path, $contents, $perms) = @_;
|
my ($path, $contents, $perms) = @_;
|
||||||
write_file("$path.tmp", { binmode => ':utf8', perms => $perms // 0644 }, $contents);
|
write_file($path, { atomic => 1, binmode => ':utf8', perms => $perms // 0644 }, $contents) or die;
|
||||||
rename("$path.tmp", $path) or die;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -98,7 +97,7 @@ sub parseGroup {
|
||||||
return ($f[0], { name => $f[0], password => $f[1], gid => $gid, members => $f[3] });
|
return ($f[0], { name => $f[0], password => $f[1], gid => $gid, members => $f[3] });
|
||||||
}
|
}
|
||||||
|
|
||||||
my %groupsCur = -f "/etc/group" ? map { parseGroup } read_file("/etc/group") : ();
|
my %groupsCur = -f "/etc/group" ? map { parseGroup } read_file("/etc/group", { binmode => ":utf8" }) : ();
|
||||||
|
|
||||||
# Read the current /etc/passwd.
|
# Read the current /etc/passwd.
|
||||||
sub parseUser {
|
sub parseUser {
|
||||||
|
@ -109,20 +108,19 @@ sub parseUser {
|
||||||
return ($f[0], { name => $f[0], fakePassword => $f[1], uid => $uid,
|
return ($f[0], { name => $f[0], fakePassword => $f[1], uid => $uid,
|
||||||
gid => $f[3], description => $f[4], home => $f[5], shell => $f[6] });
|
gid => $f[3], description => $f[4], home => $f[5], shell => $f[6] });
|
||||||
}
|
}
|
||||||
|
my %usersCur = -f "/etc/passwd" ? map { parseUser } read_file("/etc/passwd", { binmode => ":utf8" }) : ();
|
||||||
my %usersCur = -f "/etc/passwd" ? map { parseUser } read_file("/etc/passwd") : ();
|
|
||||||
|
|
||||||
# Read the groups that were created declaratively (i.e. not by groups)
|
# Read the groups that were created declaratively (i.e. not by groups)
|
||||||
# in the past. These must be removed if they are no longer in the
|
# in the past. These must be removed if they are no longer in the
|
||||||
# current spec.
|
# current spec.
|
||||||
my $declGroupsFile = "/var/lib/nixos/declarative-groups";
|
my $declGroupsFile = "/var/lib/nixos/declarative-groups";
|
||||||
my %declGroups;
|
my %declGroups;
|
||||||
$declGroups{$_} = 1 foreach split / /, -e $declGroupsFile ? read_file($declGroupsFile) : "";
|
$declGroups{$_} = 1 foreach split / /, -e $declGroupsFile ? read_file($declGroupsFile, { binmode => ":utf8" }) : "";
|
||||||
|
|
||||||
# Idem for the users.
|
# Idem for the users.
|
||||||
my $declUsersFile = "/var/lib/nixos/declarative-users";
|
my $declUsersFile = "/var/lib/nixos/declarative-users";
|
||||||
my %declUsers;
|
my %declUsers;
|
||||||
$declUsers{$_} = 1 foreach split / /, -e $declUsersFile ? read_file($declUsersFile) : "";
|
$declUsers{$_} = 1 foreach split / /, -e $declUsersFile ? read_file($declUsersFile, { binmode => ":utf8" }) : "";
|
||||||
|
|
||||||
|
|
||||||
# Generate a new /etc/group containing the declared groups.
|
# Generate a new /etc/group containing the declared groups.
|
||||||
|
@ -175,7 +173,7 @@ foreach my $name (keys %groupsCur) {
|
||||||
# Rewrite /etc/group. FIXME: acquire lock.
|
# Rewrite /etc/group. FIXME: acquire lock.
|
||||||
my @lines = map { join(":", $_->{name}, $_->{password}, $_->{gid}, $_->{members}) . "\n" }
|
my @lines = map { join(":", $_->{name}, $_->{password}, $_->{gid}, $_->{members}) . "\n" }
|
||||||
(sort { $a->{gid} <=> $b->{gid} } values(%groupsOut));
|
(sort { $a->{gid} <=> $b->{gid} } values(%groupsOut));
|
||||||
updateFile($gidMapFile, encode_json($gidMap));
|
updateFile($gidMapFile, to_json($gidMap));
|
||||||
updateFile("/etc/group", \@lines);
|
updateFile("/etc/group", \@lines);
|
||||||
system("nscd --invalidate group");
|
system("nscd --invalidate group");
|
||||||
|
|
||||||
|
@ -251,7 +249,7 @@ foreach my $name (keys %usersCur) {
|
||||||
# Rewrite /etc/passwd. FIXME: acquire lock.
|
# Rewrite /etc/passwd. FIXME: acquire lock.
|
||||||
@lines = map { join(":", $_->{name}, $_->{fakePassword}, $_->{uid}, $_->{gid}, $_->{description}, $_->{home}, $_->{shell}) . "\n" }
|
@lines = map { join(":", $_->{name}, $_->{fakePassword}, $_->{uid}, $_->{gid}, $_->{description}, $_->{home}, $_->{shell}) . "\n" }
|
||||||
(sort { $a->{uid} <=> $b->{uid} } (values %usersOut));
|
(sort { $a->{uid} <=> $b->{uid} } (values %usersOut));
|
||||||
updateFile($uidMapFile, encode_json($uidMap));
|
updateFile($uidMapFile, to_json($uidMap));
|
||||||
updateFile("/etc/passwd", \@lines);
|
updateFile("/etc/passwd", \@lines);
|
||||||
system("nscd --invalidate passwd");
|
system("nscd --invalidate passwd");
|
||||||
|
|
||||||
|
@ -260,7 +258,7 @@ system("nscd --invalidate passwd");
|
||||||
my @shadowNew;
|
my @shadowNew;
|
||||||
my %shadowSeen;
|
my %shadowSeen;
|
||||||
|
|
||||||
foreach my $line (-f "/etc/shadow" ? read_file("/etc/shadow") : ()) {
|
foreach my $line (-f "/etc/shadow" ? read_file("/etc/shadow", { binmode => ":utf8" }) : ()) {
|
||||||
chomp $line;
|
chomp $line;
|
||||||
my ($name, $hashedPassword, @rest) = split(':', $line, -9);
|
my ($name, $hashedPassword, @rest) = split(':', $line, -9);
|
||||||
my $u = $usersOut{$name};;
|
my $u = $usersOut{$name};;
|
||||||
|
|
Loading…
Reference in a new issue