diff --git a/nixos/modules/config/users-groups.nix b/nixos/modules/config/users-groups.nix
index 97bf6726279..e38593d5602 100644
--- a/nixos/modules/config/users-groups.nix
+++ b/nixos/modules/config/users-groups.nix
@@ -7,6 +7,24 @@ let
ids = config.ids;
cfg = config.users;
+ passwordDescription = ''
+ The options hashedPassword,
+ password and passwordFile
+ controls what password is set for the user.
+ hashedPassword overrides both
+ password and passwordFile.
+ password overrides passwordFile.
+ If none of these three options are set, no password is assigned to
+ the user, and the user will not be able to do password logins.
+ If the option users.mutableUsers is true, the
+ password defined in one of the three options will only be set when
+ the user is created for the first time. After that, you are free to
+ change the password with the ordinary user management commands. If
+ users.mutableUsers is false, you cannot change
+ user passwords, they will always be set according to the password
+ options.
+ '';
+
userOpts = { name, config, ... }: {
options = {
@@ -76,24 +94,24 @@ let
'';
};
+ hashedPassword = mkOption {
+ type = with types; uniq (nullOr str);
+ default = null;
+ description = ''
+ Specifies the (hashed) password for the user.
+ ${passwordDescription}
+ '';
+ };
+
password = mkOption {
type = with types; uniq (nullOr str);
default = null;
description = ''
- The user's password. If undefined, no password is set for
- the user. Warning: do not set confidential information here
- because it is world-readable in the Nix store. This option
- should only be used for public accounts such as
- guest.
- The option password overrides
- passwordFile, if both are specified.
- If none of the options password or
- passwordFile are specified, the user account will
- be locked for password logins. This is the default behavior except
- for the root account, which has an empty password by default. If you
- want to lock the root account for password logins, set
- users.extraUsers.root.password to
- null.
+ Specifies the (clear text) password for the user.
+ Warning: do not set confidential information here
+ because it is world-readable in the Nix store. This option
+ should only be used for public accounts.
+ ${passwordDescription}
'';
};
@@ -105,8 +123,7 @@ let
file is read on each system activation. The file should contain
exactly one line, which should be the password in an encrypted form
that is suitable for the chpasswd -e command.
- See the password for more details on how passwords
- are assigned.
+ ${passwordDescription}
'';
};
@@ -297,6 +314,26 @@ in
options = [ groupOpts ];
};
+ security.initialRootPassword = mkOption {
+ type = types.str;
+ default = "";
+ example = "!";
+ description = ''
+ The (hashed) password for the root account set on initial
+ installation. The empty string denotes that root can login
+ locally without a password (but not via remote services such
+ as SSH, or indirectly via su or
+ sudo). The string !
+ prevents root from logging in using a password.
+ Note, setting this option sets
+ users.extraUsers.root.hashedPassword.
+ Note, if users.mutableUsers is false
+ you cannot change the root password manually, so in that case
+ the name of this option is a bit misleading, since it will define
+ the root password beyond the user initialisation phase.
+ '';
+ };
+
};
@@ -311,7 +348,7 @@ in
home = "/root";
shell = cfg.defaultUserShell;
group = "root";
- password = mkDefault "";
+ hashedPassword = config.security.initialRootPassword;
};
nobody = {
uid = ids.uids.nobody;
@@ -351,17 +388,21 @@ in
test "$(getent shadow '${u.name}' | cut -d: -f2)" != "x" && setpw=no
''}
if [ "$setpw" == "yes" ]; then
- ${if u.password == ""
+ ${if !(isNull u.hashedPassword)
+ then ''
+ echo "${u.name}:${u.hashedPassword}" | \
+ ${pkgs.shadow}/sbin/chpasswd -e''
+ else if u.password == ""
then "passwd -d '${u.name}' &>/dev/null"
- else if (isNull u.password && isNull u.passwordFile)
- then "passwd -l '${u.name}' &>/dev/null"
else if !(isNull u.password)
then ''
echo "${u.name}:${u.password}" | ${pkgs.shadow}/sbin/chpasswd''
- else ''
+ else if !(isNull u.passwordFile)
+ then ''
echo -n "${u.name}:" | cat - "${u.passwordFile}" | \
${pkgs.shadow}/sbin/chpasswd -e
''
+ else "passwd -l '${u.name}' &>/dev/null"
}
fi
'';
diff --git a/nixos/modules/virtualisation/amazon-image.nix b/nixos/modules/virtualisation/amazon-image.nix
index 701e95af7d3..abd2a1084bd 100644
--- a/nixos/modules/virtualisation/amazon-image.nix
+++ b/nixos/modules/virtualisation/amazon-image.nix
@@ -164,5 +164,5 @@ with pkgs.lib;
# Prevent logging in as root without a password. This doesn't really matter,
# since the only PAM services that allow logging in with a null
# password are local ones that are inaccessible on EC2 machines.
- users.extraUsers.root.password = null;
+ security.initialRootPassword = "!";
}
diff --git a/nixos/modules/virtualisation/virtualbox-image.nix b/nixos/modules/virtualisation/virtualbox-image.nix
index a89c8264a33..71bdf31a98d 100644
--- a/nixos/modules/virtualisation/virtualbox-image.nix
+++ b/nixos/modules/virtualisation/virtualbox-image.nix
@@ -111,5 +111,5 @@ with pkgs.lib;
# Prevent logging in as root without a password. For NixOps, we
# don't need this because the user can login via SSH, and for the
# demo images, there is a demo user account that can sudo to root.
- users.extraUsers.root.password = null;
+ security.initialRootPassword = "!";
}