summary refs log tree commit diff
path: root/nixos
diff options
context:
space:
mode:
authorMichele Guerini Rocco <rnhmjoj@users.noreply.github.com>2020-07-07 10:57:51 +0200
committerGitHub <noreply@github.com>2020-07-07 10:57:51 +0200
commit01c4a388ee49f3df5c71fb2886c926beda660577 (patch)
tree2488149ab1b8468804cb3920d4893e49fa98c5da /nixos
parent3734ac91602a108e51e322078f5b52a0526d3d48 (diff)
parentc37347af7eaa0177e3a374dd94158ff546f20fdb (diff)
downloadnixpkgs-01c4a388ee49f3df5c71fb2886c926beda660577.tar
nixpkgs-01c4a388ee49f3df5c71fb2886c926beda660577.tar.gz
nixpkgs-01c4a388ee49f3df5c71fb2886c926beda660577.tar.bz2
nixpkgs-01c4a388ee49f3df5c71fb2886c926beda660577.tar.lz
nixpkgs-01c4a388ee49f3df5c71fb2886c926beda660577.tar.xz
nixpkgs-01c4a388ee49f3df5c71fb2886c926beda660577.tar.zst
nixpkgs-01c4a388ee49f3df5c71fb2886c926beda660577.zip
Merge pull request #91238 from rnhmjoj/users
nixos/users-groups: do not check validity of special hashes
Diffstat (limited to 'nixos')
-rw-r--r--nixos/modules/config/users-groups.nix66
1 files changed, 42 insertions, 24 deletions
diff --git a/nixos/modules/config/users-groups.nix b/nixos/modules/config/users-groups.nix
index c2f16e5ed8e..12d9be94663 100644
--- a/nixos/modules/config/users-groups.nix
+++ b/nixos/modules/config/users-groups.nix
@@ -6,6 +6,16 @@ let
   ids = config.ids;
   cfg = config.users;
 
+  # Check whether a password hash will allow login.
+  allowsLogin = hash:
+    hash == "" # login without password
+    || !(lib.elem hash
+      [ null   # password login disabled
+        "!"    # password login disabled
+        "!!"   # a variant of "!"
+        "*"    # password unset
+      ]);
+
   passwordDescription = ''
     The options <option>hashedPassword</option>,
     <option>password</option> and <option>passwordFile</option>
@@ -25,17 +35,19 @@ let
   '';
 
   hashedPasswordDescription = ''
-    To generate hashed password install <literal>mkpasswd</literal>
+    To generate a hashed password install the <literal>mkpasswd</literal>
     package and run <literal>mkpasswd -m sha-512</literal>.
 
-    For password-less logins without password prompt, use
-    the empty string <literal>""</literal>.
-
-    For logins with a fixed password (including the empty-string password with
-    prompt), use one of the un-hashed password options instead, such as
-    <option>users.users.&lt;name?&gt;.password</option>.
+    If set to an empty string (<literal>""</literal>), this user will
+    be able to log in without being asked for a password (but not via remote
+    services such as SSH, or indirectly via <command>su</command> or
+    <command>sudo</command>). This should only be used for e.g. bootable
+    live systems. Note: this is different from setting an empty password,
+    which ca be achieved using <option>users.users.&lt;name?&gt;.password</option>.
 
-    Such unprotected logins should only be used for e.g. bootable live systems.
+    If set to <literal>null</literal> (default) this user will not
+    be able to log in using a password (i.e. via <command>login</command>
+    command).
   '';
 
   userOpts = { name, config, ... }: {
@@ -415,6 +427,12 @@ in {
   imports = [
     (mkAliasOptionModule [ "users" "extraUsers" ] [ "users" "users" ])
     (mkAliasOptionModule [ "users" "extraGroups" ] [ "users" "groups" ])
+    (mkChangedOptionModule
+      [ "security" "initialRootPassword" ]
+      [ "users" "users" "root" "initialHashedPassword" ]
+      (cfg: if cfg.security.initialHashedPassword == "!"
+            then null
+            else cfg.security.initialHashedPassword))
   ];
 
   ###### interface
@@ -486,14 +504,6 @@ in {
       '';
     };
 
-    # FIXME: obsolete - will remove.
-    security.initialRootPassword = mkOption {
-      type = types.str;
-      default = "!";
-      example = "";
-      visible = false;
-    };
-
   };
 
 
@@ -508,7 +518,6 @@ in {
         home = "/root";
         shell = mkDefault cfg.defaultUserShell;
         group = "root";
-        initialHashedPassword = mkDefault config.security.initialRootPassword;
       };
       nobody = {
         uid = ids.uids.nobody;
@@ -597,7 +606,7 @@ in {
              || cfg.group == "wheel"
              || elem "wheel" cfg.extraGroups)
             &&
-            ((cfg.hashedPassword != null && cfg.hashedPassword != "!")
+            (allowsLogin cfg.hashedPassword
              || cfg.password != null
              || cfg.passwordFile != null
              || cfg.openssh.authorizedKeys.keys != []
@@ -607,7 +616,17 @@ in {
           Neither the root account nor any wheel user has a password or SSH authorized key.
           You must set one to prevent being locked out of your system.'';
       }
-    ];
+    ] ++ flip mapAttrsToList cfg.users (name: user:
+      {
+        assertion = (user.hashedPassword != null)
+                    -> (builtins.match ".*:.*" user.hashedPassword == null);
+        message = ''
+          The password hash of user "${name}" contains a ":" character.
+          This is invalid and would break the login system because the fields
+          of /etc/shadow (file where hashes are stored) are colon-separated.
+          Please check the value of option `users.users."${name}".hashedPassword`.'';
+      }
+    );
 
     warnings =
       builtins.filter (x: x != null) (
@@ -630,14 +649,13 @@ in {
           content = "${base64}${sep}${base64}";
           mcf = "^${sep}${scheme}${sep}${content}$";
         in
-        if (user.hashedPassword != null
+        if (allowsLogin user.hashedPassword
+            && user.hashedPassword != ""  # login without password
             && builtins.match mcf user.hashedPassword == null)
-        then
-        ''
+        then ''
           The password hash of user "${name}" may be invalid. You must set a
           valid hash or the user will be locked out of their account. Please
-          check the value of option `users.users."${name}".hashedPassword`.
-        ''
+          check the value of option `users.users."${name}".hashedPassword`.''
         else null
       ));