Merge pull request from symphorien/usertype

nixos/users: require one of users.users.name.{isSystemUser,isNormalUser}
This commit is contained in:
Guillaume Girol 2021-04-14 19:38:26 +00:00 committed by GitHub
commit f1a2ab6818
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
23 changed files with 80 additions and 32 deletions

@ -167,7 +167,7 @@ in {
# We know that the `user` attribute exists because we set a default value
# for it above, allowing us to use it without worries here
users.users.${cfg.settings.user} = {};
users.users.${cfg.settings.user} = { isSystemUser = true; };
# ...
};

@ -845,6 +845,13 @@ environment.systemPackages = [
The option's description was incorrect regarding ownership management and has been simplified greatly.
</para>
</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>
<para>
The GNOME desktop manager once again installs <package>gnome3.epiphany</package> by default.

@ -306,6 +306,7 @@ in {
description = "PulseAudio system service user";
home = stateDir;
createHome = true;
isSystemUser = true;
};
users.groups.pulse.gid = gid;

@ -92,6 +92,8 @@ let
the user's UID is allocated in the range for system users
(below 500) or in the range for normal users (starting at
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>,
and <option>isSystemUser</option> to
<literal>false</literal>.
Exactly one of <literal>isNormalUser</literal> and
<literal>isSystemUser</literal> must be true.
'';
};
@ -521,6 +525,7 @@ in {
};
nobody = {
uid = ids.uids.nobody;
isSystemUser = true;
description = "Unprivileged account (don't use!)";
group = "nogroup";
};
@ -608,17 +613,28 @@ 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:
{
] ++ flatten (flip mapAttrsToList cfg.users (name: user:
[
{
assertion = (user.hashedPassword != null)
-> (builtins.match ".*:.*" user.hashedPassword == null);
-> (builtins.match ".*:.*" user.hashedPassword == null);
message = ''
The password hash of user "${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."${user.name}".hashedPassword`.'';
}
);
The password hash of user "${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."${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 =
builtins.filter (x: x != null) (

@ -169,6 +169,7 @@ let
(map (mkAuthorizedKey cfg false) cfg.authorizedKeys
++ map (mkAuthorizedKey cfg true) cfg.authorizedKeysAppendOnly);
useDefaultShell = true;
isSystemUser = true;
};
groups.${cfg.group} = { };
};

@ -197,6 +197,7 @@ in {
group = pgmanage;
home = cfg.sqlRoot;
createHome = true;
isSystemUser = true;
};
groups.${pgmanage} = {
name = pgmanage;

@ -64,6 +64,7 @@ in
users.users = mkIf (cfg.user == "bazarr") {
bazarr = {
isSystemUser = true;
group = cfg.group;
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
here except "nixbld". */
uid = builtins.add config.ids.uids.nixbld nr;
isSystemUser = true;
group = "nixbld";
extraGroups = [ "nixbld" ];
};

@ -34,7 +34,10 @@ in {
users = {
groups._tuptime.members = [ "_tuptime" ];
users._tuptime.description = "tuptime database owner";
users._tuptime = {
isSystemUser = true;
description = "tuptime database owner";
};
};
systemd = {

@ -73,6 +73,7 @@ let
users.${variant} = {
description = "BIRD Internet Routing Daemon user";
group = variant;
isSystemUser = true;
};
groups.${variant} = {};
};

@ -243,8 +243,10 @@ in
xlog.journal = true;
};
users.users.ncdns =
{ description = "ncdns daemon user"; };
users.users.ncdns = {
isSystemUser = true;
description = "ncdns daemon user";
};
systemd.services.ncdns = {
description = "ncdns daemon";

@ -93,6 +93,7 @@ in
users.users.pixiecore = {
description = "Pixiecore daemon user";
group = "pixiecore";
isSystemUser = true;
};
networking.firewall = mkIf cfg.openFirewall {

@ -75,6 +75,7 @@ in {
description = "Pleroma user";
home = cfg.stateDir;
extraGroups = [ cfg.group ];
isSystemUser = true;
};
groups."${cfg.group}" = {};
};

@ -264,6 +264,7 @@ in
users.users.privacyidea = mkIf (cfg.user == "privacyidea") {
group = cfg.group;
isSystemUser = true;
};
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") {
group = cfg.ldap-proxy.group;
isSystemUser = true;
};
users.groups.pi-ldap-proxy = mkIf (cfg.ldap-proxy.group == "pi-ldap-proxy") {};

@ -607,6 +607,7 @@ in {
home = "${cfg.home}";
group = "nextcloud";
createHome = true;
isSystemUser = true;
};
users.groups.nextcloud.members = [ "nextcloud" config.services.nginx.user ];

@ -31,7 +31,7 @@ in {
firewall.allowedTCPPorts = [ 3306 4444 4567 4568 ];
firewall.allowedUDPPorts = [ 4567 ];
};
users.users.testuser = { };
users.users.testuser = { isSystemUser = true; };
systemd.services.mysql = with pkgs; {
path = [ mysqlenv-common mysqlenv-mariabackup ];
};
@ -89,7 +89,7 @@ in {
firewall.allowedTCPPorts = [ 3306 4444 4567 4568 ];
firewall.allowedUDPPorts = [ 4567 ];
};
users.users.testuser = { };
users.users.testuser = { isSystemUser = true; };
systemd.services.mysql = with pkgs; {
path = [ mysqlenv-common mysqlenv-mariabackup ];
};
@ -136,7 +136,7 @@ in {
firewall.allowedTCPPorts = [ 3306 4444 4567 4568 ];
firewall.allowedUDPPorts = [ 4567 ];
};
users.users.testuser = { };
users.users.testuser = { isSystemUser = true; };
systemd.services.mysql = with pkgs; {
path = [ mysqlenv-common mysqlenv-mariabackup ];
};

@ -31,7 +31,7 @@ in {
firewall.allowedTCPPorts = [ 3306 4444 4567 4568 ];
firewall.allowedUDPPorts = [ 4567 ];
};
users.users.testuser = { };
users.users.testuser = { isSystemUser = true; };
systemd.services.mysql = with pkgs; {
path = [ mysqlenv-common mysqlenv-rsync ];
};
@ -84,7 +84,7 @@ in {
firewall.allowedTCPPorts = [ 3306 4444 4567 4568 ];
firewall.allowedUDPPorts = [ 4567 ];
};
users.users.testuser = { };
users.users.testuser = { isSystemUser = true; };
systemd.services.mysql = with pkgs; {
path = [ mysqlenv-common mysqlenv-rsync ];
};
@ -130,7 +130,7 @@ in {
firewall.allowedTCPPorts = [ 3306 4444 4567 4568 ];
firewall.allowedUDPPorts = [ 4567 ];
};
users.users.testuser = { };
users.users.testuser = { isSystemUser = true; };
systemd.services.mysql = with pkgs; {
path = [ mysqlenv-common mysqlenv-rsync ];
};

@ -9,8 +9,8 @@ import ./../make-test-python.nix ({ pkgs, ...} : {
{ pkgs, ... }:
{
users.users.testuser = { };
users.users.testuser2 = { };
users.users.testuser = { isSystemUser = true; };
users.users.testuser2 = { isSystemUser = true; };
services.mysql.enable = true;
services.mysql.initialDatabases = [
{ 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
virtualisation.memorySize = 1024;
users.users.testuser = { };
users.users.testuser2 = { };
users.users.testuser = { isSystemUser = true; };
users.users.testuser2 = { isSystemUser = true; };
services.mysql.enable = true;
services.mysql.initialDatabases = [
{ name = "testdb3"; schema = ./testdb.sql; }
@ -75,8 +75,8 @@ import ./../make-test-python.nix ({ pkgs, ...} : {
{ pkgs, ... }:
{
users.users.testuser = { };
users.users.testuser2 = { };
users.users.testuser = { isSystemUser = true; };
users.users.testuser2 = { isSystemUser = true; };
services.mysql.enable = true;
services.mysql.initialScript = pkgs.writeText "mariadb-init.sql" ''
ALTER USER root@localhost IDENTIFIED WITH unix_socket;

@ -22,11 +22,10 @@ in
users.users."member" = {
createHome = false;
description = "A member of the redis group";
isNormalUser = true;
extraGroups = [
"redis"
];
group = "users";
shell = "/bin/sh";
};
};
};

@ -274,7 +274,10 @@ in
I find cows to be evil don't you?
'';
users.users.tester.password = "test";
users.users.tester = {
isNormalUser = true;
password = "test";
};
services.postfix = {
enable = true;
destination = ["example.com"];

@ -13,14 +13,17 @@ in import ./make-test-python.nix ({ pkgs, ... }: {
users = {
mutableUsers = true;
users.emma = {
isNormalUser = true;
password = password1;
shell = pkgs.bash;
};
users.layla = {
isNormalUser = true;
password = password2;
shell = pkgs.shadow;
};
users.ash = {
isNormalUser = true;
password = password4;
shell = pkgs.bash;
};

@ -150,6 +150,7 @@ import ./make-test-python.nix {
config.users.groups.chroot-testgroup = {};
config.users.users.chroot-testuser = {
isSystemUser = true;
description = "Chroot Test User";
group = "chroot-testgroup";
};

@ -132,12 +132,15 @@ import ./make-test-python.nix ({ pkgs, lib, ... }:
users.users = {
# user that is permitted to access the unix socket
someuser.extraGroups = [
config.users.users.unbound.group
];
someuser = {
isSystemUser = true;
extraGroups = [
config.users.users.unbound.group
];
};
# user that is not permitted to access the unix socket
unauthorizeduser = {};
unauthorizeduser = { isSystemUser = true; };
};
environment.etc = {