lol

nixos/user-groups: add a toggle for user account creation (#358646)

authored by

Sandro and committed by
GitHub
d1c535f6 622ad6b3

+123 -12
+2
nixos/doc/manual/release-notes/rl-2505.section.md
··· 555 555 556 556 - `gerbera` now has wavpack support. 557 557 558 + - 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. 559 + 558 560 - `ddclient` was updated from 3.11.2 to 4.0.0 [Release notes](https://github.com/ddclient/ddclient/releases/tag/v4.0.0) 559 561 560 562 <!-- To avoid merge conflicts, consider adding your item at an arbitrary place in the list instead. -->
+11 -1
nixos/modules/config/users-groups.nix
··· 124 124 125 125 options = { 126 126 127 + enable = mkOption { 128 + type = types.bool; 129 + default = true; 130 + example = false; 131 + description = '' 132 + If set to false, the user account will not be created. This is useful for when you wish to conditionally 133 + disable user accounts. 134 + ''; 135 + }; 136 + 127 137 name = mkOption { 128 138 type = types.passwdEntry types.str; 129 139 apply = x: assert (stringLength x < 32 || abort "Username '${x}' is longer than 31 characters which is not allowed!"); x; ··· 557 567 autoSubUidGidRange subUidRanges subGidRanges 558 568 initialPassword initialHashedPassword expires; 559 569 shell = utils.toShellPath u.shell; 560 - }) cfg.users; 570 + }) (filterAttrs (_: u: u.enable) cfg.users); 561 571 groups = attrValues cfg.groups; 562 572 }); 563 573
+18 -11
nixos/modules/services/system/userborn.nix
··· 31 31 ; 32 32 isNormal = opts.isNormalUser; 33 33 shell = utils.toShellPath opts.shell; 34 - }) config.users.users; 34 + }) (lib.filterAttrs (_: u: u.enable) config.users.users); 35 35 }; 36 36 37 37 userbornConfigJson = pkgs.writeText "userborn.json" (builtins.toJSON userbornConfig); ··· 95 95 96 96 # Create home directories, do not create /var/empty even if that's a user's 97 97 # home. 98 - tmpfiles.settings.home-directories = lib.mapAttrs' ( 99 - username: opts: 100 - lib.nameValuePair (toString opts.home) { 101 - d = { 102 - mode = opts.homeMode; 103 - user = opts.name; 104 - inherit (opts) group; 105 - }; 106 - } 107 - ) (lib.filterAttrs (_username: opts: opts.createHome && opts.home != "/var/empty") userCfg.users); 98 + tmpfiles.settings.home-directories = 99 + lib.mapAttrs' 100 + ( 101 + username: opts: 102 + lib.nameValuePair (toString opts.home) { 103 + d = { 104 + mode = opts.homeMode; 105 + user = opts.name; 106 + inherit (opts) group; 107 + }; 108 + } 109 + ) 110 + ( 111 + lib.filterAttrs ( 112 + _username: opts: opts.enable && opts.createHome && opts.home != "/var/empty" 113 + ) userCfg.users 114 + ); 108 115 109 116 services.userborn = { 110 117 wantedBy = [ "sysinit.target" ];
+1
nixos/tests/all-tests.nix
··· 1201 1201 userborn-mutable-etc = runTest ./userborn-mutable-etc.nix; 1202 1202 userborn-immutable-etc = runTest ./userborn-immutable-etc.nix; 1203 1203 user-activation-scripts = handleTest ./user-activation-scripts.nix {}; 1204 + user-enable-option = runTest ./user-enable-option.nix; 1204 1205 user-expiry = runTest ./user-expiry.nix; 1205 1206 user-home-mode = handleTest ./user-home-mode.nix {}; 1206 1207 ustreamer = handleTest ./ustreamer.nix {};
+82
nixos/tests/user-enable-option.nix
··· 1 + let 2 + normal-enabled = "username-normal-enabled"; 3 + normal-disabled = "username-normal-disabled"; 4 + system-enabled = "username-system-enabled"; 5 + system-disabled = "username-system-disabled"; 6 + passwd = "enableOptionPasswd"; 7 + in 8 + { 9 + name = "user-enable-option"; 10 + 11 + nodes.machine = { 12 + users = { 13 + groups.test-group = { }; 14 + users = { 15 + # User is enabled (default behaviour). 16 + ${normal-enabled} = { 17 + enable = true; 18 + isNormalUser = true; 19 + initialPassword = passwd; 20 + }; 21 + 22 + # User is disabled. 23 + ${normal-disabled} = { 24 + enable = false; 25 + isNormalUser = true; 26 + initialPassword = passwd; 27 + }; 28 + 29 + # User is a system user, and is enabled. 30 + ${system-enabled} = { 31 + enable = true; 32 + isSystemUser = true; 33 + initialPassword = passwd; 34 + group = "test-group"; 35 + }; 36 + 37 + # User is a system user, and is disabled. 38 + ${system-disabled} = { 39 + enable = false; 40 + isSystemUser = true; 41 + initialPassword = passwd; 42 + group = "test-group"; 43 + }; 44 + }; 45 + }; 46 + }; 47 + 48 + testScript = '' 49 + def switch_to_tty(tty_number): 50 + machine.fail(f"pgrep -f 'agetty.*tty{tty_number}'") 51 + machine.send_key(f"alt-f{tty_number}") 52 + machine.wait_until_succeeds(f"[ $(fgconsole) = {tty_number} ]") 53 + machine.wait_for_unit(f"getty@tty{tty_number}.service") 54 + machine.wait_until_succeeds(f"pgrep -f 'agetty.*tty{tty_number}'") 55 + 56 + machine.wait_for_unit("multi-user.target") 57 + machine.wait_for_unit("getty@tty1.service") 58 + 59 + with subtest("${normal-enabled} exists"): 60 + check_fn = f"id ${normal-enabled}" 61 + machine.succeed(check_fn) 62 + machine.wait_until_tty_matches("1", "login: ") 63 + machine.send_chars("${normal-enabled}\n") 64 + machine.wait_until_tty_matches("1", "Password: ") 65 + machine.send_chars("${passwd}\n") 66 + 67 + with subtest("${normal-disabled} does not exist"): 68 + switch_to_tty(2) 69 + check_fn = f"id ${normal-disabled}" 70 + machine.fail(check_fn) 71 + 72 + with subtest("${system-enabled} exists"): 73 + switch_to_tty(3) 74 + check_fn = f"id ${system-enabled}" 75 + machine.succeed(check_fn) 76 + 77 + with subtest("${system-disabled} does not exist"): 78 + switch_to_tty(4) 79 + check_fn = f"id ${system-disabled}" 80 + machine.fail(check_fn) 81 + ''; 82 + }
+9
nixos/tests/userborn.nix
··· 66 66 isNormalUser = true; 67 67 hashedPassword = newNormaloHashedPassword; 68 68 }; 69 + normalo-disabled = { 70 + enable = false; 71 + isNormalUser = true; 72 + }; 69 73 }; 70 74 groups = { 71 75 new-group = { }; ··· 95 99 print(machine.succeed("getent passwd sysuser")) 96 100 assert 1000 > int(machine.succeed("id --user sysuser")), "sysuser user doesn't have a system UID" 97 101 assert "${sysuserInitialHashedPassword}" in machine.succeed("getent shadow sysuser"), "system user password is not correct" 102 + 103 + with subtest("normalo-disabled is NOT created"): 104 + machine.fail("id normalo-disabled") 105 + # Check if user's home has been created 106 + machine.fail("[ -d '/home/normalo-disabled' ]") 98 107 99 108 with subtest("sysusers group is created"): 100 109 print(machine.succeed("getent group sysusers"))