nixos/users: require one of users.users.name.{isSystemUser,isNormalUser}
As the only consequence of isSystemUser is that if the uid is null then it's allocated below 500, if a user has uid = something below 500 then we don't require isSystemUser to be set. Motivation: https://github.com/NixOS/nixpkgs/issues/112647
This commit is contained in:
parent
311ceed827
commit
7a87973b4c
|
@ -167,7 +167,7 @@ in {
|
||||||
|
|
||||||
# We know that the `user` attribute exists because we set a default value
|
# We know that the `user` attribute exists because we set a default value
|
||||||
# for it above, allowing us to use it without worries here
|
# for it above, allowing us to use it without worries here
|
||||||
users.users.${cfg.settings.user} = {};
|
users.users.${cfg.settings.user} = { isSystemUser = true; };
|
||||||
|
|
||||||
# ...
|
# ...
|
||||||
};
|
};
|
||||||
|
|
|
@ -839,6 +839,13 @@ environment.systemPackages = [
|
||||||
The option's description was incorrect regarding ownership management and has been simplified greatly.
|
The option's description was incorrect regarding ownership management and has been simplified greatly.
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
When defining a new user, one of <xref linkend="opt-users.users._name_.isNormalUser" /> and <xref linkend="opt-users.users._name_.isSystemUser" /> is now required.
|
||||||
|
This is to prevent accidentally giving a UID above 1000 to system users, which could have unexpected consequences, like running user activation scripts for system users.
|
||||||
|
Note that users defined with an explicit UID below 500 are exempted from this check, as <xref linkend="opt-users.users._name_.isSystemUser" /> has no effect for those.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
The GNOME desktop manager once again installs <package>gnome3.epiphany</package> by default.
|
The GNOME desktop manager once again installs <package>gnome3.epiphany</package> by default.
|
||||||
|
|
|
@ -306,6 +306,7 @@ in {
|
||||||
description = "PulseAudio system service user";
|
description = "PulseAudio system service user";
|
||||||
home = stateDir;
|
home = stateDir;
|
||||||
createHome = true;
|
createHome = true;
|
||||||
|
isSystemUser = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
users.groups.pulse.gid = gid;
|
users.groups.pulse.gid = gid;
|
||||||
|
|
|
@ -92,6 +92,8 @@ let
|
||||||
the user's UID is allocated in the range for system users
|
the user's UID is allocated in the range for system users
|
||||||
(below 500) or in the range for normal users (starting at
|
(below 500) or in the range for normal users (starting at
|
||||||
1000).
|
1000).
|
||||||
|
Exactly one of <literal>isNormalUser</literal> and
|
||||||
|
<literal>isSystemUser</literal> must be true.
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -107,6 +109,8 @@ let
|
||||||
<option>useDefaultShell</option> to <literal>true</literal>,
|
<option>useDefaultShell</option> to <literal>true</literal>,
|
||||||
and <option>isSystemUser</option> to
|
and <option>isSystemUser</option> to
|
||||||
<literal>false</literal>.
|
<literal>false</literal>.
|
||||||
|
Exactly one of <literal>isNormalUser</literal> and
|
||||||
|
<literal>isSystemUser</literal> must be true.
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -521,6 +525,7 @@ in {
|
||||||
};
|
};
|
||||||
nobody = {
|
nobody = {
|
||||||
uid = ids.uids.nobody;
|
uid = ids.uids.nobody;
|
||||||
|
isSystemUser = true;
|
||||||
description = "Unprivileged account (don't use!)";
|
description = "Unprivileged account (don't use!)";
|
||||||
group = "nogroup";
|
group = "nogroup";
|
||||||
};
|
};
|
||||||
|
@ -608,7 +613,8 @@ in {
|
||||||
Neither the root account nor any wheel user has a password or SSH authorized key.
|
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.'';
|
You must set one to prevent being locked out of your system.'';
|
||||||
}
|
}
|
||||||
] ++ flip mapAttrsToList cfg.users (name: user:
|
] ++ flatten (flip mapAttrsToList cfg.users (name: user:
|
||||||
|
[
|
||||||
{
|
{
|
||||||
assertion = (user.hashedPassword != null)
|
assertion = (user.hashedPassword != null)
|
||||||
-> (builtins.match ".*:.*" user.hashedPassword == null);
|
-> (builtins.match ".*:.*" user.hashedPassword == null);
|
||||||
|
@ -618,7 +624,17 @@ in {
|
||||||
of /etc/shadow (file where hashes are stored) are colon-separated.
|
of /etc/shadow (file where hashes are stored) are colon-separated.
|
||||||
Please check the value of option `users.users."${user.name}".hashedPassword`.'';
|
Please check the value of option `users.users."${user.name}".hashedPassword`.'';
|
||||||
}
|
}
|
||||||
);
|
{
|
||||||
|
assertion = let
|
||||||
|
xor = a: b: a && !b || b && !a;
|
||||||
|
isEffectivelySystemUser = user.isSystemUser || (user.uid != null && user.uid < 500);
|
||||||
|
in xor isEffectivelySystemUser user.isNormalUser;
|
||||||
|
message = ''
|
||||||
|
Exactly one of users.users.${user.name}.isSystemUser and users.users.${user.name}.isNormalUser must be set.
|
||||||
|
'';
|
||||||
|
}
|
||||||
|
]
|
||||||
|
));
|
||||||
|
|
||||||
warnings =
|
warnings =
|
||||||
builtins.filter (x: x != null) (
|
builtins.filter (x: x != null) (
|
||||||
|
|
|
@ -169,6 +169,7 @@ let
|
||||||
(map (mkAuthorizedKey cfg false) cfg.authorizedKeys
|
(map (mkAuthorizedKey cfg false) cfg.authorizedKeys
|
||||||
++ map (mkAuthorizedKey cfg true) cfg.authorizedKeysAppendOnly);
|
++ map (mkAuthorizedKey cfg true) cfg.authorizedKeysAppendOnly);
|
||||||
useDefaultShell = true;
|
useDefaultShell = true;
|
||||||
|
isSystemUser = true;
|
||||||
};
|
};
|
||||||
groups.${cfg.group} = { };
|
groups.${cfg.group} = { };
|
||||||
};
|
};
|
||||||
|
|
|
@ -197,6 +197,7 @@ in {
|
||||||
group = pgmanage;
|
group = pgmanage;
|
||||||
home = cfg.sqlRoot;
|
home = cfg.sqlRoot;
|
||||||
createHome = true;
|
createHome = true;
|
||||||
|
isSystemUser = true;
|
||||||
};
|
};
|
||||||
groups.${pgmanage} = {
|
groups.${pgmanage} = {
|
||||||
name = pgmanage;
|
name = pgmanage;
|
||||||
|
|
|
@ -64,6 +64,7 @@ in
|
||||||
|
|
||||||
users.users = mkIf (cfg.user == "bazarr") {
|
users.users = mkIf (cfg.user == "bazarr") {
|
||||||
bazarr = {
|
bazarr = {
|
||||||
|
isSystemUser = true;
|
||||||
group = cfg.group;
|
group = cfg.group;
|
||||||
home = "/var/lib/${config.systemd.services.bazarr.serviceConfig.StateDirectory}";
|
home = "/var/lib/${config.systemd.services.bazarr.serviceConfig.StateDirectory}";
|
||||||
};
|
};
|
||||||
|
|
|
@ -21,6 +21,7 @@ let
|
||||||
calls in `libstore/build.cc', don't add any supplementary group
|
calls in `libstore/build.cc', don't add any supplementary group
|
||||||
here except "nixbld". */
|
here except "nixbld". */
|
||||||
uid = builtins.add config.ids.uids.nixbld nr;
|
uid = builtins.add config.ids.uids.nixbld nr;
|
||||||
|
isSystemUser = true;
|
||||||
group = "nixbld";
|
group = "nixbld";
|
||||||
extraGroups = [ "nixbld" ];
|
extraGroups = [ "nixbld" ];
|
||||||
};
|
};
|
||||||
|
|
|
@ -34,7 +34,10 @@ in {
|
||||||
|
|
||||||
users = {
|
users = {
|
||||||
groups._tuptime.members = [ "_tuptime" ];
|
groups._tuptime.members = [ "_tuptime" ];
|
||||||
users._tuptime.description = "tuptime database owner";
|
users._tuptime = {
|
||||||
|
isSystemUser = true;
|
||||||
|
description = "tuptime database owner";
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
systemd = {
|
systemd = {
|
||||||
|
|
|
@ -73,6 +73,7 @@ let
|
||||||
users.${variant} = {
|
users.${variant} = {
|
||||||
description = "BIRD Internet Routing Daemon user";
|
description = "BIRD Internet Routing Daemon user";
|
||||||
group = variant;
|
group = variant;
|
||||||
|
isSystemUser = true;
|
||||||
};
|
};
|
||||||
groups.${variant} = {};
|
groups.${variant} = {};
|
||||||
};
|
};
|
||||||
|
|
|
@ -243,8 +243,10 @@ in
|
||||||
xlog.journal = true;
|
xlog.journal = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
users.users.ncdns =
|
users.users.ncdns = {
|
||||||
{ description = "ncdns daemon user"; };
|
isSystemUser = true;
|
||||||
|
description = "ncdns daemon user";
|
||||||
|
};
|
||||||
|
|
||||||
systemd.services.ncdns = {
|
systemd.services.ncdns = {
|
||||||
description = "ncdns daemon";
|
description = "ncdns daemon";
|
||||||
|
|
|
@ -93,6 +93,7 @@ in
|
||||||
users.users.pixiecore = {
|
users.users.pixiecore = {
|
||||||
description = "Pixiecore daemon user";
|
description = "Pixiecore daemon user";
|
||||||
group = "pixiecore";
|
group = "pixiecore";
|
||||||
|
isSystemUser = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
networking.firewall = mkIf cfg.openFirewall {
|
networking.firewall = mkIf cfg.openFirewall {
|
||||||
|
|
|
@ -75,6 +75,7 @@ in {
|
||||||
description = "Pleroma user";
|
description = "Pleroma user";
|
||||||
home = cfg.stateDir;
|
home = cfg.stateDir;
|
||||||
extraGroups = [ cfg.group ];
|
extraGroups = [ cfg.group ];
|
||||||
|
isSystemUser = true;
|
||||||
};
|
};
|
||||||
groups."${cfg.group}" = {};
|
groups."${cfg.group}" = {};
|
||||||
};
|
};
|
||||||
|
|
|
@ -264,6 +264,7 @@ in
|
||||||
|
|
||||||
users.users.privacyidea = mkIf (cfg.user == "privacyidea") {
|
users.users.privacyidea = mkIf (cfg.user == "privacyidea") {
|
||||||
group = cfg.group;
|
group = cfg.group;
|
||||||
|
isSystemUser = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
users.groups.privacyidea = mkIf (cfg.group == "privacyidea") {};
|
users.groups.privacyidea = mkIf (cfg.group == "privacyidea") {};
|
||||||
|
@ -294,6 +295,7 @@ in
|
||||||
|
|
||||||
users.users.pi-ldap-proxy = mkIf (cfg.ldap-proxy.user == "pi-ldap-proxy") {
|
users.users.pi-ldap-proxy = mkIf (cfg.ldap-proxy.user == "pi-ldap-proxy") {
|
||||||
group = cfg.ldap-proxy.group;
|
group = cfg.ldap-proxy.group;
|
||||||
|
isSystemUser = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
users.groups.pi-ldap-proxy = mkIf (cfg.ldap-proxy.group == "pi-ldap-proxy") {};
|
users.groups.pi-ldap-proxy = mkIf (cfg.ldap-proxy.group == "pi-ldap-proxy") {};
|
||||||
|
|
|
@ -607,6 +607,7 @@ in {
|
||||||
home = "${cfg.home}";
|
home = "${cfg.home}";
|
||||||
group = "nextcloud";
|
group = "nextcloud";
|
||||||
createHome = true;
|
createHome = true;
|
||||||
|
isSystemUser = true;
|
||||||
};
|
};
|
||||||
users.groups.nextcloud.members = [ "nextcloud" config.services.nginx.user ];
|
users.groups.nextcloud.members = [ "nextcloud" config.services.nginx.user ];
|
||||||
|
|
||||||
|
|
|
@ -31,7 +31,7 @@ in {
|
||||||
firewall.allowedTCPPorts = [ 3306 4444 4567 4568 ];
|
firewall.allowedTCPPorts = [ 3306 4444 4567 4568 ];
|
||||||
firewall.allowedUDPPorts = [ 4567 ];
|
firewall.allowedUDPPorts = [ 4567 ];
|
||||||
};
|
};
|
||||||
users.users.testuser = { };
|
users.users.testuser = { isSystemUser = true; };
|
||||||
systemd.services.mysql = with pkgs; {
|
systemd.services.mysql = with pkgs; {
|
||||||
path = [ mysqlenv-common mysqlenv-mariabackup ];
|
path = [ mysqlenv-common mysqlenv-mariabackup ];
|
||||||
};
|
};
|
||||||
|
@ -89,7 +89,7 @@ in {
|
||||||
firewall.allowedTCPPorts = [ 3306 4444 4567 4568 ];
|
firewall.allowedTCPPorts = [ 3306 4444 4567 4568 ];
|
||||||
firewall.allowedUDPPorts = [ 4567 ];
|
firewall.allowedUDPPorts = [ 4567 ];
|
||||||
};
|
};
|
||||||
users.users.testuser = { };
|
users.users.testuser = { isSystemUser = true; };
|
||||||
systemd.services.mysql = with pkgs; {
|
systemd.services.mysql = with pkgs; {
|
||||||
path = [ mysqlenv-common mysqlenv-mariabackup ];
|
path = [ mysqlenv-common mysqlenv-mariabackup ];
|
||||||
};
|
};
|
||||||
|
@ -136,7 +136,7 @@ in {
|
||||||
firewall.allowedTCPPorts = [ 3306 4444 4567 4568 ];
|
firewall.allowedTCPPorts = [ 3306 4444 4567 4568 ];
|
||||||
firewall.allowedUDPPorts = [ 4567 ];
|
firewall.allowedUDPPorts = [ 4567 ];
|
||||||
};
|
};
|
||||||
users.users.testuser = { };
|
users.users.testuser = { isSystemUser = true; };
|
||||||
systemd.services.mysql = with pkgs; {
|
systemd.services.mysql = with pkgs; {
|
||||||
path = [ mysqlenv-common mysqlenv-mariabackup ];
|
path = [ mysqlenv-common mysqlenv-mariabackup ];
|
||||||
};
|
};
|
||||||
|
|
|
@ -31,7 +31,7 @@ in {
|
||||||
firewall.allowedTCPPorts = [ 3306 4444 4567 4568 ];
|
firewall.allowedTCPPorts = [ 3306 4444 4567 4568 ];
|
||||||
firewall.allowedUDPPorts = [ 4567 ];
|
firewall.allowedUDPPorts = [ 4567 ];
|
||||||
};
|
};
|
||||||
users.users.testuser = { };
|
users.users.testuser = { isSystemUser = true; };
|
||||||
systemd.services.mysql = with pkgs; {
|
systemd.services.mysql = with pkgs; {
|
||||||
path = [ mysqlenv-common mysqlenv-rsync ];
|
path = [ mysqlenv-common mysqlenv-rsync ];
|
||||||
};
|
};
|
||||||
|
@ -84,7 +84,7 @@ in {
|
||||||
firewall.allowedTCPPorts = [ 3306 4444 4567 4568 ];
|
firewall.allowedTCPPorts = [ 3306 4444 4567 4568 ];
|
||||||
firewall.allowedUDPPorts = [ 4567 ];
|
firewall.allowedUDPPorts = [ 4567 ];
|
||||||
};
|
};
|
||||||
users.users.testuser = { };
|
users.users.testuser = { isSystemUser = true; };
|
||||||
systemd.services.mysql = with pkgs; {
|
systemd.services.mysql = with pkgs; {
|
||||||
path = [ mysqlenv-common mysqlenv-rsync ];
|
path = [ mysqlenv-common mysqlenv-rsync ];
|
||||||
};
|
};
|
||||||
|
@ -130,7 +130,7 @@ in {
|
||||||
firewall.allowedTCPPorts = [ 3306 4444 4567 4568 ];
|
firewall.allowedTCPPorts = [ 3306 4444 4567 4568 ];
|
||||||
firewall.allowedUDPPorts = [ 4567 ];
|
firewall.allowedUDPPorts = [ 4567 ];
|
||||||
};
|
};
|
||||||
users.users.testuser = { };
|
users.users.testuser = { isSystemUser = true; };
|
||||||
systemd.services.mysql = with pkgs; {
|
systemd.services.mysql = with pkgs; {
|
||||||
path = [ mysqlenv-common mysqlenv-rsync ];
|
path = [ mysqlenv-common mysqlenv-rsync ];
|
||||||
};
|
};
|
||||||
|
|
|
@ -9,8 +9,8 @@ import ./../make-test-python.nix ({ pkgs, ...} : {
|
||||||
{ pkgs, ... }:
|
{ pkgs, ... }:
|
||||||
|
|
||||||
{
|
{
|
||||||
users.users.testuser = { };
|
users.users.testuser = { isSystemUser = true; };
|
||||||
users.users.testuser2 = { };
|
users.users.testuser2 = { isSystemUser = true; };
|
||||||
services.mysql.enable = true;
|
services.mysql.enable = true;
|
||||||
services.mysql.initialDatabases = [
|
services.mysql.initialDatabases = [
|
||||||
{ name = "testdb3"; schema = ./testdb.sql; }
|
{ name = "testdb3"; schema = ./testdb.sql; }
|
||||||
|
@ -44,8 +44,8 @@ import ./../make-test-python.nix ({ pkgs, ...} : {
|
||||||
# Kernel panic - not syncing: Out of memory: compulsory panic_on_oom is enabled
|
# Kernel panic - not syncing: Out of memory: compulsory panic_on_oom is enabled
|
||||||
virtualisation.memorySize = 1024;
|
virtualisation.memorySize = 1024;
|
||||||
|
|
||||||
users.users.testuser = { };
|
users.users.testuser = { isSystemUser = true; };
|
||||||
users.users.testuser2 = { };
|
users.users.testuser2 = { isSystemUser = true; };
|
||||||
services.mysql.enable = true;
|
services.mysql.enable = true;
|
||||||
services.mysql.initialDatabases = [
|
services.mysql.initialDatabases = [
|
||||||
{ name = "testdb3"; schema = ./testdb.sql; }
|
{ name = "testdb3"; schema = ./testdb.sql; }
|
||||||
|
@ -75,8 +75,8 @@ import ./../make-test-python.nix ({ pkgs, ...} : {
|
||||||
{ pkgs, ... }:
|
{ pkgs, ... }:
|
||||||
|
|
||||||
{
|
{
|
||||||
users.users.testuser = { };
|
users.users.testuser = { isSystemUser = true; };
|
||||||
users.users.testuser2 = { };
|
users.users.testuser2 = { isSystemUser = true; };
|
||||||
services.mysql.enable = true;
|
services.mysql.enable = true;
|
||||||
services.mysql.initialScript = pkgs.writeText "mariadb-init.sql" ''
|
services.mysql.initialScript = pkgs.writeText "mariadb-init.sql" ''
|
||||||
ALTER USER root@localhost IDENTIFIED WITH unix_socket;
|
ALTER USER root@localhost IDENTIFIED WITH unix_socket;
|
||||||
|
|
|
@ -22,11 +22,10 @@ in
|
||||||
users.users."member" = {
|
users.users."member" = {
|
||||||
createHome = false;
|
createHome = false;
|
||||||
description = "A member of the redis group";
|
description = "A member of the redis group";
|
||||||
|
isNormalUser = true;
|
||||||
extraGroups = [
|
extraGroups = [
|
||||||
"redis"
|
"redis"
|
||||||
];
|
];
|
||||||
group = "users";
|
|
||||||
shell = "/bin/sh";
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -274,7 +274,10 @@ in
|
||||||
|
|
||||||
I find cows to be evil don't you?
|
I find cows to be evil don't you?
|
||||||
'';
|
'';
|
||||||
users.users.tester.password = "test";
|
users.users.tester = {
|
||||||
|
isNormalUser = true;
|
||||||
|
password = "test";
|
||||||
|
};
|
||||||
services.postfix = {
|
services.postfix = {
|
||||||
enable = true;
|
enable = true;
|
||||||
destination = ["example.com"];
|
destination = ["example.com"];
|
||||||
|
|
|
@ -13,14 +13,17 @@ in import ./make-test-python.nix ({ pkgs, ... }: {
|
||||||
users = {
|
users = {
|
||||||
mutableUsers = true;
|
mutableUsers = true;
|
||||||
users.emma = {
|
users.emma = {
|
||||||
|
isNormalUser = true;
|
||||||
password = password1;
|
password = password1;
|
||||||
shell = pkgs.bash;
|
shell = pkgs.bash;
|
||||||
};
|
};
|
||||||
users.layla = {
|
users.layla = {
|
||||||
|
isNormalUser = true;
|
||||||
password = password2;
|
password = password2;
|
||||||
shell = pkgs.shadow;
|
shell = pkgs.shadow;
|
||||||
};
|
};
|
||||||
users.ash = {
|
users.ash = {
|
||||||
|
isNormalUser = true;
|
||||||
password = password4;
|
password = password4;
|
||||||
shell = pkgs.bash;
|
shell = pkgs.bash;
|
||||||
};
|
};
|
||||||
|
|
|
@ -150,6 +150,7 @@ import ./make-test-python.nix {
|
||||||
|
|
||||||
config.users.groups.chroot-testgroup = {};
|
config.users.groups.chroot-testgroup = {};
|
||||||
config.users.users.chroot-testuser = {
|
config.users.users.chroot-testuser = {
|
||||||
|
isSystemUser = true;
|
||||||
description = "Chroot Test User";
|
description = "Chroot Test User";
|
||||||
group = "chroot-testgroup";
|
group = "chroot-testgroup";
|
||||||
};
|
};
|
||||||
|
|
|
@ -132,12 +132,15 @@ import ./make-test-python.nix ({ pkgs, lib, ... }:
|
||||||
|
|
||||||
users.users = {
|
users.users = {
|
||||||
# user that is permitted to access the unix socket
|
# user that is permitted to access the unix socket
|
||||||
someuser.extraGroups = [
|
someuser = {
|
||||||
|
isSystemUser = true;
|
||||||
|
extraGroups = [
|
||||||
config.users.users.unbound.group
|
config.users.users.unbound.group
|
||||||
];
|
];
|
||||||
|
};
|
||||||
|
|
||||||
# user that is not permitted to access the unix socket
|
# user that is not permitted to access the unix socket
|
||||||
unauthorizeduser = {};
|
unauthorizeduser = { isSystemUser = true; };
|
||||||
};
|
};
|
||||||
|
|
||||||
environment.etc = {
|
environment.etc = {
|
||||||
|
|
Loading…
Reference in New Issue