summary refs log tree commit diff
path: root/nixos/modules/config/update-users-groups.pl
diff options
context:
space:
mode:
authorEelco Dolstra <eelco.dolstra@logicblox.com>2014-10-31 17:39:19 +0100
committerEelco Dolstra <eelco.dolstra@logicblox.com>2014-10-31 17:42:09 +0100
commita9f5e77e2f9b0e27ff6d3998b3c29c88dede1a7d (patch)
treea38300d0a959c503081610c66008093bd4f98478 /nixos/modules/config/update-users-groups.pl
parent919ed14477d2e305d47604be5b6b19a0cbeaed98 (diff)
downloadnixlib-a9f5e77e2f9b0e27ff6d3998b3c29c88dede1a7d.tar
nixlib-a9f5e77e2f9b0e27ff6d3998b3c29c88dede1a7d.tar.gz
nixlib-a9f5e77e2f9b0e27ff6d3998b3c29c88dede1a7d.tar.bz2
nixlib-a9f5e77e2f9b0e27ff6d3998b3c29c88dede1a7d.tar.lz
nixlib-a9f5e77e2f9b0e27ff6d3998b3c29c88dede1a7d.tar.xz
nixlib-a9f5e77e2f9b0e27ff6d3998b3c29c88dede1a7d.tar.zst
nixlib-a9f5e77e2f9b0e27ff6d3998b3c29c88dede1a7d.zip
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.
Diffstat (limited to 'nixos/modules/config/update-users-groups.pl')
-rw-r--r--nixos/modules/config/update-users-groups.pl34
1 files changed, 17 insertions, 17 deletions
diff --git a/nixos/modules/config/update-users-groups.pl b/nixos/modules/config/update-users-groups.pl
index 197b65e27c4b..abcb082af8e5 100644
--- a/nixos/modules/config/update-users-groups.pl
+++ b/nixos/modules/config/update-users-groups.pl
@@ -6,6 +6,15 @@ use JSON;
 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
 # /etc/login.defs.
 sub allocId {
@@ -174,6 +183,8 @@ foreach my $u (@{$spec->{users}}) {
         } else {
             warn "warning: password file ‘$u->{passwordFile}’ does not exist\n";
         }
+    } elsif (defined $u->{password}) {
+        $u->{hashedPassword} = hashPassword($u->{password});
     }
 
     $u->{fakePassword} = $existing->{fakePassword} // "x";
@@ -208,32 +219,21 @@ my %shadowSeen;
 
 foreach my $line (-f "/etc/shadow" ? read_file("/etc/shadow") : ()) {
     chomp $line;
-    my ($name, $password, @rest) = split(':', $line, -9);
+    my ($name, $hashedPassword, @rest) = split(':', $line, -9);
     my $u = $usersOut{$name};;
     next if !defined $u;
-    $password = $u->{hashedPassword} if defined $u->{hashedPassword} && !$spec->{mutableUsers}; # FIXME
-    push @shadowNew, join(":", $name, $password, @rest) . "\n";
+    $hashedPassword = $u->{hashedPassword} if defined $u->{hashedPassword} && !$spec->{mutableUsers}; # FIXME
+    push @shadowNew, join(":", $name, $hashedPassword, @rest) . "\n";
     $shadowSeen{$name} = 1;
 }
 
 foreach my $u (values %usersOut) {
     next if defined $shadowSeen{$u->{name}};
-    my $password = "!";
-    $password = $u->{hashedPassword} if defined $u->{hashedPassword};
+    my $hashedPassword = "!";
+    $hashedPassword = $u->{hashedPassword} if defined $u->{hashedPassword};
     # 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);
 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";
-    }
-}