From a15a3d9f1f9fadd455b38b3833e1ee6db6b59186 Mon Sep 17 00:00:00 2001 From: Michael Hoang Date: Mon, 28 Oct 2024 10:47:15 +1100 Subject: [PATCH 1/3] users: fix unclosed string --- modules/users/default.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/users/default.nix b/modules/users/default.nix index a23251dc..92c0cd8a 100644 --- a/modules/users/default.nix +++ b/modules/users/default.nix @@ -190,7 +190,7 @@ in homeDirectory=''${homeDirectory#NFSHomeDirectory: } if [[ ${lib.escapeShellArg v.home} != "$homeDirectory" ]]; then printf >&2 '\e[1;31merror: config contains the wrong home directory for %s, aborting activation\e[0m\n' ${name} - printf >&2 'nix-darwin does not support changing the home directory of existing users. + printf >&2 'nix-darwin does not support changing the home directory of existing users.\n' printf >&2 '\n' printf >&2 'Please set:\n' printf >&2 '\n' From c908607e8a8ac1aaa0db60955800be4b02e500cc Mon Sep 17 00:00:00 2001 From: Michael Hoang Date: Mon, 28 Oct 2024 01:05:16 +1100 Subject: [PATCH 2/3] users: remove `users.forceRecreate` option --- modules/users/default.nix | 78 +++++++++------------------------------ 1 file changed, 18 insertions(+), 60 deletions(-) diff --git a/modules/users/default.nix b/modules/users/default.nix index 92c0cd8a..58156d24 100644 --- a/modules/users/default.nix +++ b/modules/users/default.nix @@ -41,6 +41,10 @@ let in { + imports = [ + (lib.mkRemovedOptionModule [ "users" "forceRecreate" ] "") + ]; + options = { users.knownGroups = mkOption { type = types.listOf types.str; @@ -85,13 +89,6 @@ in type = types.attrsOf types.str; default = {}; }; - - users.forceRecreate = mkOption { - internal = true; - type = types.bool; - default = false; - description = "Remove and recreate existing groups/users."; - }; }; config = { @@ -152,33 +149,11 @@ in fi } - ensureDeletable() { - # TODO: add `darwin.primaryUser` as well - if [[ "$1" == "$USER" ]]; then - printf >&2 '\e[1;31merror: refusing to delete the user calling `darwin-rebuild` (%s), aborting activation\e[0m\n', "$1" - exit 1 - elif [[ "$1" == "root" ]]; then - printf >&2 '\e[1;31merror: refusing to delete `root`, aborting activation\e[0m\n' - exit 1 - fi - - ensurePerms "$1" delete - } ${concatMapStringsSep "\n" (v: let name = lib.escapeShellArg v.name; dsclUser = lib.escapeShellArg "/Users/${v.name}"; in '' - ${optionalString cfg.forceRecreate '' - u=$(id -u ${name} 2> /dev/null) || true - if [[ "$u" -eq ${toString v.uid} ]]; then - # TODO: add `darwin.primaryUser` as well - if [[ ${name} != "$USER" && ${name} != "root" ]]; then - ensureDeletable ${name} - fi - fi - ''} - u=$(id -u ${name} 2> /dev/null) || true if ! [[ -n "$u" && "$u" -ne "${toString v.uid}" ]]; then if [ -z "$u" ]; then @@ -203,11 +178,22 @@ in fi '') createdUsers} - ${concatMapStringsSep "\n" (name: '' - u=$(id -u ${lib.escapeShellArg name} 2> /dev/null) || true + ${concatMapStringsSep "\n" (v: let + name = lib.escapeShellArg v; + in '' + u=$(id -u ${name} 2> /dev/null) || true if [ -n "$u" ]; then if [ "$u" -gt 501 ]; then - ensureDeletable ${lib.escapeShellArg name} + # TODO: add `darwin.primaryUser` as well + if [[ ${name} == "$USER" ]]; then + printf >&2 '\e[1;31merror: refusing to delete the user calling `darwin-rebuild` (%s), aborting activation\e[0m\n', ${name} + exit 1 + elif [[ ${name} == "root" ]]; then + printf >&2 '\e[1;31merror: refusing to delete `root`, aborting activation\e[0m\n' + exit 1 + fi + + ensurePerms ${name} delete fi fi '') deletedUsers} @@ -219,17 +205,6 @@ in ${concatMapStringsSep "\n" (v: let dsclGroup = lib.escapeShellArg "/Groups/${v.name}"; in '' - ${optionalString cfg.forceRecreate '' - g=$(dscl . -read ${dsclGroup} PrimaryGroupID 2> /dev/null) || true - g=''${g#PrimaryGroupID: } - if [[ "$g" -eq ${toString v.gid} ]]; then - echo "deleting group ${v.name}..." >&2 - dscl . -delete ${dsclGroup} - else - echo "warning: existing group '${v.name}' has unexpected gid $g, skipping..." >&2 - fi - ''} - g=$(dscl . -read ${dsclGroup} PrimaryGroupID 2> /dev/null) || true g=''${g#PrimaryGroupID: } if [ -z "$g" ]; then @@ -273,23 +248,6 @@ in name = lib.escapeShellArg v.name; dsclUser = lib.escapeShellArg "/Users/${v.name}"; in '' - ${optionalString cfg.forceRecreate '' - u=$(id -u ${name} 2> /dev/null) || true - if [[ "$u" -eq ${toString v.uid} ]]; then - # TODO: add `darwin.primaryUser` as well - if [[ ${name} == "$SUDO_USER" ]]; then - printf >&2 'warning: not going to recreate the user calling `darwin-rebuild` (%s), skipping...\n' "$SUDO_USER" - elif [[ ${name} == "root" ]]; then - printf >&2 'warning: not going to recreate root, skipping...\n' - else - printf >&2 'deleting user ${v.name}...\n' - dscl . -delete ${dsclUser} - fi - else - echo "warning: existing user '${v.name}' has unexpected uid $u, skipping..." >&2 - fi - ''} - u=$(id -u ${name} 2> /dev/null) || true if [[ -n "$u" && "$u" -ne "${toString v.uid}" ]]; then echo "warning: existing user '${v.name}' has unexpected uid $u, skipping..." >&2 From f380194f3dac82e63dc72db160490dcb58208534 Mon Sep 17 00:00:00 2001 From: Michael Hoang Date: Mon, 28 Oct 2024 10:30:02 +1100 Subject: [PATCH 3/3] users: create users with home directory `/var/empty` by default --- modules/users/default.nix | 2 +- modules/users/user.nix | 8 +++----- tests/users-groups.nix | 2 +- 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/modules/users/default.nix b/modules/users/default.nix index 58156d24..a945fb48 100644 --- a/modules/users/default.nix +++ b/modules/users/default.nix @@ -260,7 +260,7 @@ in "-UID" v.uid "-GID" v.gid ] ++ (lib.optionals (v.description != null) [ "-fullName" v.description ]) - ++ (lib.optionals (v.home != null) [ "-home" v.home ]) + ++ [ "-home" (if v.home != null then v.home else "/var/empty") ] ++ [ "-shell" (if v.shell != null then shellPath v.shell else "/usr/bin/false") ])} 2> /dev/null # We need to check as `sysadminctl -addUser` still exits with exit code 0 when there's an error diff --git a/modules/users/user.nix b/modules/users/user.nix index 72ae07b8..9689e052 100644 --- a/modules/users/user.nix +++ b/modules/users/user.nix @@ -58,11 +58,9 @@ description = '' The user's home directory. This defaults to `null`. - When this is set to `null`, the value is managed by macOS instead of - `nix-darwin`. This means if the user has not been created yet, - `sysadminctl` will be called without the `-home` flag which means the - user will have a default home directory of `/Users/` which will - be created by `sysadminctl`. + When this is set to `null`, if the user has not been created yet, + they will be created with the home directory `/var/empty` to match + the old default. ''; }; diff --git a/tests/users-groups.nix b/tests/users-groups.nix index 34ee5c24..81261057 100644 --- a/tests/users-groups.nix +++ b/tests/users-groups.nix @@ -51,7 +51,7 @@ grep "sysadminctl -addUser ${lib.escapeShellArgs [ "foo" "-UID" 42000 "-GID" 42000 "-fullName" "Foo user" "-home" "/Users/foo" "-shell" "/run/current-system/sw/bin/bash" ]}" ${config.out}/activate grep "createhomedir -cu ${lib.escapeShellArg "foo"}" ${config.out}/activate grep "sysadminctl -addUser ${lib.escapeShellArgs [ "created.user" "-UID" 42001 ]} .* ${lib.escapeShellArgs [ "-shell" "/usr/bin/false" ] }" ${config.out}/activate - (! grep "sysadminctl -addUser ${lib.escapeShellArg "created.user"} .* -home" ${config.out}/activate) + grep "sysadminctl -addUser ${lib.escapeShellArg "created.user"} .* ${lib.escapeShellArgs [ "-home" "/var/empty" ]}" ${config.out}/activate (! grep "dscl . -delete ${lib.escapeShellArg "/Users/created.user"}" ${config.out}/activate) (! grep "dscl . -delete ${lib.escapeShellArg "/Groups/created.user"}" ${config.out}/activate)