Re-introduce security.initialRootPassword, and add a new option users.extraUsers.<user>.hashedPassword
This commit is contained in:
parent
03ee174032
commit
0b92ad02c8
|
@ -7,6 +7,24 @@ let
|
||||||
ids = config.ids;
|
ids = config.ids;
|
||||||
cfg = config.users;
|
cfg = config.users;
|
||||||
|
|
||||||
|
passwordDescription = ''
|
||||||
|
The options <literal>hashedPassword</literal>,
|
||||||
|
<literal>password</literal> and <literal>passwordFile</literal>
|
||||||
|
controls what password is set for the user.
|
||||||
|
<literal>hashedPassword</literal> overrides both
|
||||||
|
<literal>password</literal> and <literal>passwordFile</literal>.
|
||||||
|
<literal>password</literal> overrides <literal>passwordFile</literal>.
|
||||||
|
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 <literal>users.mutableUsers</literal> 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
|
||||||
|
<literal>users.mutableUsers</literal> is false, you cannot change
|
||||||
|
user passwords, they will always be set according to the password
|
||||||
|
options.
|
||||||
|
'';
|
||||||
|
|
||||||
userOpts = { name, config, ... }: {
|
userOpts = { name, config, ... }: {
|
||||||
|
|
||||||
options = {
|
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 {
|
password = mkOption {
|
||||||
type = with types; uniq (nullOr str);
|
type = with types; uniq (nullOr str);
|
||||||
default = null;
|
default = null;
|
||||||
description = ''
|
description = ''
|
||||||
The user's password. If undefined, no password is set for
|
Specifies the (clear text) password for the user.
|
||||||
the user. Warning: do not set confidential information here
|
Warning: do not set confidential information here
|
||||||
because it is world-readable in the Nix store. This option
|
because it is world-readable in the Nix store. This option
|
||||||
should only be used for public accounts such as
|
should only be used for public accounts.
|
||||||
<literal>guest</literal>.
|
${passwordDescription}
|
||||||
The option <literal>password</literal> overrides
|
|
||||||
<literal>passwordFile</literal>, if both are specified.
|
|
||||||
If none of the options <literal>password</literal> or
|
|
||||||
<literal>passwordFile</literal> 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
|
|
||||||
<literal>users.extraUsers.root.password</literal> to
|
|
||||||
<literal>null</literal>.
|
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -105,8 +123,7 @@ let
|
||||||
file is read on each system activation. The file should contain
|
file is read on each system activation. The file should contain
|
||||||
exactly one line, which should be the password in an encrypted form
|
exactly one line, which should be the password in an encrypted form
|
||||||
that is suitable for the <literal>chpasswd -e</literal> command.
|
that is suitable for the <literal>chpasswd -e</literal> command.
|
||||||
See the <literal>password</literal> for more details on how passwords
|
${passwordDescription}
|
||||||
are assigned.
|
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -297,6 +314,26 @@ in
|
||||||
options = [ groupOpts ];
|
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 <command>su</command> or
|
||||||
|
<command>sudo</command>). The string <literal>!</literal>
|
||||||
|
prevents root from logging in using a password.
|
||||||
|
Note, setting this option sets
|
||||||
|
<literal>users.extraUsers.root.hashedPassword</literal>.
|
||||||
|
Note, if <literal>users.mutableUsers</literal> 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";
|
home = "/root";
|
||||||
shell = cfg.defaultUserShell;
|
shell = cfg.defaultUserShell;
|
||||||
group = "root";
|
group = "root";
|
||||||
password = mkDefault "";
|
hashedPassword = config.security.initialRootPassword;
|
||||||
};
|
};
|
||||||
nobody = {
|
nobody = {
|
||||||
uid = ids.uids.nobody;
|
uid = ids.uids.nobody;
|
||||||
|
@ -351,17 +388,21 @@ in
|
||||||
test "$(getent shadow '${u.name}' | cut -d: -f2)" != "x" && setpw=no
|
test "$(getent shadow '${u.name}' | cut -d: -f2)" != "x" && setpw=no
|
||||||
''}
|
''}
|
||||||
if [ "$setpw" == "yes" ]; then
|
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"
|
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)
|
else if !(isNull u.password)
|
||||||
then ''
|
then ''
|
||||||
echo "${u.name}:${u.password}" | ${pkgs.shadow}/sbin/chpasswd''
|
echo "${u.name}:${u.password}" | ${pkgs.shadow}/sbin/chpasswd''
|
||||||
else ''
|
else if !(isNull u.passwordFile)
|
||||||
|
then ''
|
||||||
echo -n "${u.name}:" | cat - "${u.passwordFile}" | \
|
echo -n "${u.name}:" | cat - "${u.passwordFile}" | \
|
||||||
${pkgs.shadow}/sbin/chpasswd -e
|
${pkgs.shadow}/sbin/chpasswd -e
|
||||||
''
|
''
|
||||||
|
else "passwd -l '${u.name}' &>/dev/null"
|
||||||
}
|
}
|
||||||
fi
|
fi
|
||||||
'';
|
'';
|
||||||
|
|
|
@ -164,5 +164,5 @@ with pkgs.lib;
|
||||||
# Prevent logging in as root without a password. This doesn't really matter,
|
# 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
|
# since the only PAM services that allow logging in with a null
|
||||||
# password are local ones that are inaccessible on EC2 machines.
|
# password are local ones that are inaccessible on EC2 machines.
|
||||||
users.extraUsers.root.password = null;
|
security.initialRootPassword = "!";
|
||||||
}
|
}
|
||||||
|
|
|
@ -111,5 +111,5 @@ with pkgs.lib;
|
||||||
# Prevent logging in as root without a password. For NixOps, we
|
# 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
|
# 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.
|
# demo images, there is a demo user account that can sudo to root.
|
||||||
users.extraUsers.root.password = null;
|
security.initialRootPassword = "!";
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue