mirror of
https://github.com/NixOS/nixpkgs.git
synced 2025-06-11 20:25:32 +03:00
nixos/systemd-sysusers: only create systemusers
systemd-sysusers cannot create normal users (i.e. with a UID > 1000). Thus we stop trying an explitily only use systemd-sysusers when there are no normal users on the system (e.g. appliances).
This commit is contained in:
parent
2441226673
commit
d43e323b4a
3 changed files with 57 additions and 42 deletions
|
@ -5,6 +5,8 @@ let
|
|||
cfg = config.systemd.sysusers;
|
||||
userCfg = config.users;
|
||||
|
||||
systemUsers = lib.filterAttrs (_username: opts: !opts.isNormalUser) userCfg.users;
|
||||
|
||||
sysusersConfig = pkgs.writeTextDir "00-nixos.conf" ''
|
||||
# Type Name ID GECOS Home directory Shell
|
||||
|
||||
|
@ -16,7 +18,7 @@ let
|
|||
in
|
||||
''u ${username} ${uid}:${opts.group} "${opts.description}" ${opts.home} ${utils.toShellPath opts.shell}''
|
||||
)
|
||||
userCfg.users)
|
||||
systemUsers)
|
||||
}
|
||||
|
||||
# Groups
|
||||
|
@ -35,15 +37,15 @@ let
|
|||
${lib.concatLines (
|
||||
(lib.mapAttrsToList
|
||||
(username: opts: "echo -n '${opts.initialHashedPassword}' > 'passwd.hashed-password.${username}'")
|
||||
(lib.filterAttrs (_username: opts: opts.initialHashedPassword != null) userCfg.users))
|
||||
(lib.filterAttrs (_username: opts: opts.initialHashedPassword != null) systemUsers))
|
||||
++
|
||||
(lib.mapAttrsToList
|
||||
(username: opts: "echo -n '${opts.initialPassword}' > 'passwd.plaintext-password.${username}'")
|
||||
(lib.filterAttrs (_username: opts: opts.initialPassword != null) userCfg.users))
|
||||
(lib.filterAttrs (_username: opts: opts.initialPassword != null) systemUsers))
|
||||
++
|
||||
(lib.mapAttrsToList
|
||||
(username: opts: "cat '${opts.hashedPasswordFile}' > 'passwd.hashed-password.${username}'")
|
||||
(lib.filterAttrs (_username: opts: opts.hashedPasswordFile != null) userCfg.users))
|
||||
(lib.filterAttrs (_username: opts: opts.hashedPasswordFile != null) systemUsers))
|
||||
)
|
||||
}
|
||||
'';
|
||||
|
@ -90,7 +92,12 @@ in
|
|||
assertion = config.users.mutableUsers -> config.system.etc.overlay.enable;
|
||||
message = "config.users.mutableUsers requires config.system.etc.overlay.enable.";
|
||||
}
|
||||
];
|
||||
] ++ lib.mapAttrsToList
|
||||
(username: opts: {
|
||||
assertion = !opts.isNormalUser;
|
||||
message = "systemd-sysusers doesn't create normal users. You can currently only use it to create system users.";
|
||||
})
|
||||
userCfg.users;
|
||||
|
||||
systemd = lib.mkMerge [
|
||||
({
|
||||
|
@ -105,7 +112,7 @@ in
|
|||
group = opts.group;
|
||||
};
|
||||
})
|
||||
(lib.filterAttrs (_username: opts: opts.home != "/var/empty") userCfg.users);
|
||||
(lib.filterAttrs (_username: opts: opts.home != "/var/empty") systemUsers);
|
||||
|
||||
# Create uid/gid marker files for those without an explicit id
|
||||
tmpfiles.settings.nixos-uid = lib.mapAttrs'
|
||||
|
@ -114,7 +121,7 @@ in
|
|||
user = username;
|
||||
};
|
||||
})
|
||||
(lib.filterAttrs (_username: opts: opts.uid == null) userCfg.users);
|
||||
(lib.filterAttrs (_username: opts: opts.uid == null) systemUsers);
|
||||
|
||||
tmpfiles.settings.nixos-gid = lib.mapAttrs'
|
||||
(groupname: opts: lib.nameValuePair "/var/lib/nixos/gid/${groupname}" {
|
||||
|
@ -140,14 +147,14 @@ in
|
|||
serviceConfig = {
|
||||
LoadCredential = lib.mapAttrsToList
|
||||
(username: opts: "passwd.hashed-password.${username}:${opts.hashedPasswordFile}")
|
||||
(lib.filterAttrs (_username: opts: opts.hashedPasswordFile != null) userCfg.users);
|
||||
(lib.filterAttrs (_username: opts: opts.hashedPasswordFile != null) systemUsers);
|
||||
SetCredential = (lib.mapAttrsToList
|
||||
(username: opts: "passwd.hashed-password.${username}:${opts.initialHashedPassword}")
|
||||
(lib.filterAttrs (_username: opts: opts.initialHashedPassword != null) userCfg.users))
|
||||
(lib.filterAttrs (_username: opts: opts.initialHashedPassword != null) systemUsers))
|
||||
++
|
||||
(lib.mapAttrsToList
|
||||
(username: opts: "passwd.plaintext-password.${username}:${opts.initialPassword}")
|
||||
(lib.filterAttrs (_username: opts: opts.initialPassword != null) userCfg.users))
|
||||
(lib.filterAttrs (_username: opts: opts.initialPassword != null) systemUsers))
|
||||
;
|
||||
};
|
||||
};
|
||||
|
|
|
@ -2,8 +2,8 @@
|
|||
|
||||
let
|
||||
rootPassword = "$y$j9T$p6OI0WN7.rSfZBOijjRdR.$xUOA2MTcB48ac.9Oc5fz8cxwLv1mMqabnn333iOzSA6";
|
||||
normaloPassword = "$y$j9T$3aiOV/8CADAK22OK2QT3/0$67OKd50Z4qTaZ8c/eRWHLIM.o3ujtC1.n9ysmJfv639";
|
||||
newNormaloPassword = "mellow";
|
||||
sysuserPassword = "$y$j9T$3aiOV/8CADAK22OK2QT3/0$67OKd50Z4qTaZ8c/eRWHLIM.o3ujtC1.n9ysmJfv639";
|
||||
newSysuserPassword = "mellow";
|
||||
in
|
||||
|
||||
{
|
||||
|
@ -19,15 +19,19 @@ in
|
|||
# Override the empty root password set by the test instrumentation
|
||||
users.users.root.hashedPasswordFile = lib.mkForce null;
|
||||
users.users.root.initialHashedPassword = rootPassword;
|
||||
users.users.normalo = {
|
||||
isNormalUser = true;
|
||||
initialHashedPassword = normaloPassword;
|
||||
users.users.sysuser = {
|
||||
isSystemUser = true;
|
||||
group = "wheel";
|
||||
home = "/sysuser";
|
||||
initialHashedPassword = sysuserPassword;
|
||||
};
|
||||
|
||||
specialisation.new-generation.configuration = {
|
||||
users.users.new-normalo = {
|
||||
isNormalUser = true;
|
||||
initialPassword = newNormaloPassword;
|
||||
users.users.new-sysuser = {
|
||||
isSystemUser = true;
|
||||
group = "wheel";
|
||||
home = "/new-sysuser";
|
||||
initialPassword = newSysuserPassword;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
@ -47,18 +51,18 @@ in
|
|||
print(machine.succeed("getent passwd root"))
|
||||
assert "${rootPassword}" in machine.succeed("getent shadow root"), "root user password is not correct"
|
||||
|
||||
with subtest("normalo user is created"):
|
||||
print(machine.succeed("getent passwd normalo"))
|
||||
assert machine.succeed("stat -c '%U' /home/normalo") == "normalo\n"
|
||||
assert "${normaloPassword}" in machine.succeed("getent shadow normalo"), "normalo user password is not correct"
|
||||
with subtest("sysuser user is created"):
|
||||
print(machine.succeed("getent passwd sysuser"))
|
||||
assert machine.succeed("stat -c '%U' /sysuser") == "sysuser\n"
|
||||
assert "${sysuserPassword}" in machine.succeed("getent shadow sysuser"), "sysuser user password is not correct"
|
||||
|
||||
|
||||
machine.succeed("/run/current-system/specialisation/new-generation/bin/switch-to-configuration switch")
|
||||
|
||||
|
||||
with subtest("new-normalo user is created after switching to new generation"):
|
||||
print(machine.succeed("getent passwd new-normalo"))
|
||||
print(machine.succeed("getent shadow new-normalo"))
|
||||
assert machine.succeed("stat -c '%U' /home/new-normalo") == "new-normalo\n"
|
||||
with subtest("new-sysuser user is created after switching to new generation"):
|
||||
print(machine.succeed("getent passwd new-sysuser"))
|
||||
print(machine.succeed("getent shadow new-sysuser"))
|
||||
assert machine.succeed("stat -c '%U' /new-sysuser") == "new-sysuser\n"
|
||||
'';
|
||||
}
|
||||
|
|
|
@ -2,8 +2,8 @@
|
|||
|
||||
let
|
||||
rootPassword = "$y$j9T$p6OI0WN7.rSfZBOijjRdR.$xUOA2MTcB48ac.9Oc5fz8cxwLv1mMqabnn333iOzSA6";
|
||||
normaloPassword = "hello";
|
||||
newNormaloPassword = "$y$j9T$p6OI0WN7.rSfZBOijjRdR.$xUOA2MTcB48ac.9Oc5fz8cxwLv1mMqabnn333iOzSA6";
|
||||
sysuserPassword = "hello";
|
||||
newSysuserPassword = "$y$j9T$p6OI0WN7.rSfZBOijjRdR.$xUOA2MTcB48ac.9Oc5fz8cxwLv1mMqabnn333iOzSA6";
|
||||
in
|
||||
|
||||
{
|
||||
|
@ -24,15 +24,19 @@ in
|
|||
# Override the empty root password set by the test instrumentation
|
||||
users.users.root.hashedPasswordFile = lib.mkForce null;
|
||||
users.users.root.initialHashedPassword = rootPassword;
|
||||
users.users.normalo = {
|
||||
isNormalUser = true;
|
||||
initialPassword = normaloPassword;
|
||||
users.users.sysuser = {
|
||||
isSystemUser = true;
|
||||
group = "wheel";
|
||||
home = "/sysuser";
|
||||
initialPassword = sysuserPassword;
|
||||
};
|
||||
|
||||
specialisation.new-generation.configuration = {
|
||||
users.users.new-normalo = {
|
||||
isNormalUser = true;
|
||||
initialHashedPassword = newNormaloPassword;
|
||||
users.users.new-sysuser = {
|
||||
isSystemUser = true;
|
||||
group = "wheel";
|
||||
home = "/new-sysuser";
|
||||
initialHashedPassword = newSysuserPassword;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
@ -43,7 +47,7 @@ in
|
|||
with subtest("systemd-sysusers.service contains the credentials"):
|
||||
sysusers_service = machine.succeed("systemctl cat systemd-sysusers.service")
|
||||
print(sysusers_service)
|
||||
assert "SetCredential=passwd.plaintext-password.normalo:${normaloPassword}" in sysusers_service
|
||||
assert "SetCredential=passwd.plaintext-password.sysuser:${sysuserPassword}" in sysusers_service
|
||||
|
||||
with subtest("Correct mode on the password files"):
|
||||
assert machine.succeed("stat -c '%a' /etc/passwd") == "644\n"
|
||||
|
@ -55,17 +59,17 @@ in
|
|||
print(machine.succeed("getent passwd root"))
|
||||
assert "${rootPassword}" in machine.succeed("getent shadow root"), "root user password is not correct"
|
||||
|
||||
with subtest("normalo user is created"):
|
||||
print(machine.succeed("getent passwd normalo"))
|
||||
assert machine.succeed("stat -c '%U' /home/normalo") == "normalo\n"
|
||||
with subtest("sysuser user is created"):
|
||||
print(machine.succeed("getent passwd sysuser"))
|
||||
assert machine.succeed("stat -c '%U' /sysuser") == "sysuser\n"
|
||||
|
||||
|
||||
machine.succeed("/run/current-system/specialisation/new-generation/bin/switch-to-configuration switch")
|
||||
|
||||
|
||||
with subtest("new-normalo user is created after switching to new generation"):
|
||||
print(machine.succeed("getent passwd new-normalo"))
|
||||
assert machine.succeed("stat -c '%U' /home/new-normalo") == "new-normalo\n"
|
||||
assert "${newNormaloPassword}" in machine.succeed("getent shadow new-normalo"), "new-normalo user password is not correct"
|
||||
with subtest("new-sysuser user is created after switching to new generation"):
|
||||
print(machine.succeed("getent passwd new-sysuser"))
|
||||
assert machine.succeed("stat -c '%U' /new-sysuser") == "new-sysuser\n"
|
||||
assert "${newSysuserPassword}" in machine.succeed("getent shadow new-sysuser"), "new-sysuser user password is not correct"
|
||||
'';
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue