nixos/user-groups: add a toggle for user account creation (#358646)
This commit is contained in:
@@ -555,6 +555,8 @@
|
||||
|
||||
- `gerbera` now has wavpack support.
|
||||
|
||||
- A toggle has been added under `users.users.<name>.enable` to allow toggling individual users conditionally. If set to false, the user account will not be created.
|
||||
|
||||
- `ddclient` was updated from 3.11.2 to 4.0.0 [Release notes](https://github.com/ddclient/ddclient/releases/tag/v4.0.0)
|
||||
|
||||
<!-- To avoid merge conflicts, consider adding your item at an arbitrary place in the list instead. -->
|
||||
|
||||
@@ -124,6 +124,16 @@ let
|
||||
|
||||
options = {
|
||||
|
||||
enable = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
example = false;
|
||||
description = ''
|
||||
If set to false, the user account will not be created. This is useful for when you wish to conditionally
|
||||
disable user accounts.
|
||||
'';
|
||||
};
|
||||
|
||||
name = mkOption {
|
||||
type = types.passwdEntry types.str;
|
||||
apply = x: assert (stringLength x < 32 || abort "Username '${x}' is longer than 31 characters which is not allowed!"); x;
|
||||
@@ -557,7 +567,7 @@ let
|
||||
autoSubUidGidRange subUidRanges subGidRanges
|
||||
initialPassword initialHashedPassword expires;
|
||||
shell = utils.toShellPath u.shell;
|
||||
}) cfg.users;
|
||||
}) (filterAttrs (_: u: u.enable) cfg.users);
|
||||
groups = attrValues cfg.groups;
|
||||
});
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ let
|
||||
;
|
||||
isNormal = opts.isNormalUser;
|
||||
shell = utils.toShellPath opts.shell;
|
||||
}) config.users.users;
|
||||
}) (lib.filterAttrs (_: u: u.enable) config.users.users);
|
||||
};
|
||||
|
||||
userbornConfigJson = pkgs.writeText "userborn.json" (builtins.toJSON userbornConfig);
|
||||
@@ -95,16 +95,23 @@ in
|
||||
|
||||
# Create home directories, do not create /var/empty even if that's a user's
|
||||
# home.
|
||||
tmpfiles.settings.home-directories = lib.mapAttrs' (
|
||||
username: opts:
|
||||
lib.nameValuePair (toString opts.home) {
|
||||
d = {
|
||||
mode = opts.homeMode;
|
||||
user = opts.name;
|
||||
inherit (opts) group;
|
||||
};
|
||||
}
|
||||
) (lib.filterAttrs (_username: opts: opts.createHome && opts.home != "/var/empty") userCfg.users);
|
||||
tmpfiles.settings.home-directories =
|
||||
lib.mapAttrs'
|
||||
(
|
||||
username: opts:
|
||||
lib.nameValuePair (toString opts.home) {
|
||||
d = {
|
||||
mode = opts.homeMode;
|
||||
user = opts.name;
|
||||
inherit (opts) group;
|
||||
};
|
||||
}
|
||||
)
|
||||
(
|
||||
lib.filterAttrs (
|
||||
_username: opts: opts.enable && opts.createHome && opts.home != "/var/empty"
|
||||
) userCfg.users
|
||||
);
|
||||
|
||||
services.userborn = {
|
||||
wantedBy = [ "sysinit.target" ];
|
||||
|
||||
@@ -1201,6 +1201,7 @@ in {
|
||||
userborn-mutable-etc = runTest ./userborn-mutable-etc.nix;
|
||||
userborn-immutable-etc = runTest ./userborn-immutable-etc.nix;
|
||||
user-activation-scripts = handleTest ./user-activation-scripts.nix {};
|
||||
user-enable-option = runTest ./user-enable-option.nix;
|
||||
user-expiry = runTest ./user-expiry.nix;
|
||||
user-home-mode = handleTest ./user-home-mode.nix {};
|
||||
ustreamer = handleTest ./ustreamer.nix {};
|
||||
|
||||
@@ -0,0 +1,82 @@
|
||||
let
|
||||
normal-enabled = "username-normal-enabled";
|
||||
normal-disabled = "username-normal-disabled";
|
||||
system-enabled = "username-system-enabled";
|
||||
system-disabled = "username-system-disabled";
|
||||
passwd = "enableOptionPasswd";
|
||||
in
|
||||
{
|
||||
name = "user-enable-option";
|
||||
|
||||
nodes.machine = {
|
||||
users = {
|
||||
groups.test-group = { };
|
||||
users = {
|
||||
# User is enabled (default behaviour).
|
||||
${normal-enabled} = {
|
||||
enable = true;
|
||||
isNormalUser = true;
|
||||
initialPassword = passwd;
|
||||
};
|
||||
|
||||
# User is disabled.
|
||||
${normal-disabled} = {
|
||||
enable = false;
|
||||
isNormalUser = true;
|
||||
initialPassword = passwd;
|
||||
};
|
||||
|
||||
# User is a system user, and is enabled.
|
||||
${system-enabled} = {
|
||||
enable = true;
|
||||
isSystemUser = true;
|
||||
initialPassword = passwd;
|
||||
group = "test-group";
|
||||
};
|
||||
|
||||
# User is a system user, and is disabled.
|
||||
${system-disabled} = {
|
||||
enable = false;
|
||||
isSystemUser = true;
|
||||
initialPassword = passwd;
|
||||
group = "test-group";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
testScript = ''
|
||||
def switch_to_tty(tty_number):
|
||||
machine.fail(f"pgrep -f 'agetty.*tty{tty_number}'")
|
||||
machine.send_key(f"alt-f{tty_number}")
|
||||
machine.wait_until_succeeds(f"[ $(fgconsole) = {tty_number} ]")
|
||||
machine.wait_for_unit(f"getty@tty{tty_number}.service")
|
||||
machine.wait_until_succeeds(f"pgrep -f 'agetty.*tty{tty_number}'")
|
||||
|
||||
machine.wait_for_unit("multi-user.target")
|
||||
machine.wait_for_unit("getty@tty1.service")
|
||||
|
||||
with subtest("${normal-enabled} exists"):
|
||||
check_fn = f"id ${normal-enabled}"
|
||||
machine.succeed(check_fn)
|
||||
machine.wait_until_tty_matches("1", "login: ")
|
||||
machine.send_chars("${normal-enabled}\n")
|
||||
machine.wait_until_tty_matches("1", "Password: ")
|
||||
machine.send_chars("${passwd}\n")
|
||||
|
||||
with subtest("${normal-disabled} does not exist"):
|
||||
switch_to_tty(2)
|
||||
check_fn = f"id ${normal-disabled}"
|
||||
machine.fail(check_fn)
|
||||
|
||||
with subtest("${system-enabled} exists"):
|
||||
switch_to_tty(3)
|
||||
check_fn = f"id ${system-enabled}"
|
||||
machine.succeed(check_fn)
|
||||
|
||||
with subtest("${system-disabled} does not exist"):
|
||||
switch_to_tty(4)
|
||||
check_fn = f"id ${system-disabled}"
|
||||
machine.fail(check_fn)
|
||||
'';
|
||||
}
|
||||
@@ -66,6 +66,10 @@ in
|
||||
isNormalUser = true;
|
||||
hashedPassword = newNormaloHashedPassword;
|
||||
};
|
||||
normalo-disabled = {
|
||||
enable = false;
|
||||
isNormalUser = true;
|
||||
};
|
||||
};
|
||||
groups = {
|
||||
new-group = { };
|
||||
@@ -96,6 +100,11 @@ in
|
||||
assert 1000 > int(machine.succeed("id --user sysuser")), "sysuser user doesn't have a system UID"
|
||||
assert "${sysuserInitialHashedPassword}" in machine.succeed("getent shadow sysuser"), "system user password is not correct"
|
||||
|
||||
with subtest("normalo-disabled is NOT created"):
|
||||
machine.fail("id normalo-disabled")
|
||||
# Check if user's home has been created
|
||||
machine.fail("[ -d '/home/normalo-disabled' ]")
|
||||
|
||||
with subtest("sysusers group is created"):
|
||||
print(machine.succeed("getent group sysusers"))
|
||||
|
||||
|
||||
Reference in New Issue
Block a user