diff --git a/nixos/modules/services/system/nscd.nix b/nixos/modules/services/system/nscd.nix index 00a87e788dc4d..43b05c5b14d12 100644 --- a/nixos/modules/services/system/nscd.nix +++ b/nixos/modules/services/system/nscd.nix @@ -50,12 +50,20 @@ in systemd.services.nscd = { description = "Name Service Cache Daemon"; - before = [ "nss-lookup.target" "nss-user-lookup.target" ]; - wants = [ "nss-lookup.target" "nss-user-lookup.target" ]; - wantedBy = [ "multi-user.target" ]; - environment = { LD_LIBRARY_PATH = nssModulesPath; }; + # We need system users to be resolveable in late-boot. nscd is the proxy between + # nss-modules in NixOS and thus if you have nss-modules providing system users + # (e.g. when using DynamicUser) then nscd needs to be available before late-boot is ready + # We add a dependency of sysinit.target to nscd to ensure + # these units are started after nscd is fully started. + unitConfig.DefaultDependencies = false; + wantedBy = [ "sysinit.target" ]; + before = [ "sysinit.target" "shutdown.target" ]; + conflicts = [ "shutdown.target" ]; + wants = [ "local-fs.target" ]; + after = [ "local-fs.target" ]; + restartTriggers = [ config.environment.etc.hosts.source config.environment.etc."nsswitch.conf".source @@ -68,20 +76,19 @@ in # privileges after all the NSS modules have read their configuration # files. So prefix the ExecStart command with "!" to prevent systemd # from dropping privileges early. See ExecStart in systemd.service(5). - serviceConfig = - { ExecStart = "!@${nscd}/sbin/nscd nscd"; - Type = "forking"; - DynamicUser = true; - RuntimeDirectory = "nscd"; - PIDFile = "/run/nscd/nscd.pid"; - Restart = "always"; - ExecReload = - [ "${nscd}/sbin/nscd --invalidate passwd" - "${nscd}/sbin/nscd --invalidate group" - "${nscd}/sbin/nscd --invalidate hosts" - ]; - }; + serviceConfig = { + ExecStart = "!@${nscd}/sbin/nscd nscd"; + Type = "forking"; + DynamicUser = true; + RuntimeDirectory = "nscd"; + PIDFile = "/run/nscd/nscd.pid"; + Restart = "always"; + ExecReload = [ + "${nscd}/sbin/nscd --invalidate passwd" + "${nscd}/sbin/nscd --invalidate group" + "${nscd}/sbin/nscd --invalidate hosts" + ]; + }; }; - }; } diff --git a/nixos/modules/system/activation/switch-to-configuration.pl b/nixos/modules/system/activation/switch-to-configuration.pl index 9e5b760434a05..1cfe29f7200a8 100755 --- a/nixos/modules/system/activation/switch-to-configuration.pl +++ b/nixos/modules/system/activation/switch-to-configuration.pl @@ -663,7 +663,7 @@ sub filter_units { } my @units_to_stop_filtered = filter_units(\%units_to_stop); - +my $start_nscd = delete $unitsToStart{"nscd.service"}; # Show dry-run actions. if ($action eq "dry-activate") { @@ -722,6 +722,7 @@ sub filter_units { print STDERR "would restart the following units: ", join(", ", sort(keys(%units_to_restart))), "\n"; } my @units_to_start_filtered = filter_units(\%units_to_start); + print STDERR "would start nscd\n" if $start_nscd; if (scalar(@units_to_start_filtered)) { print STDERR "would start the following units: ", join(", ", @units_to_start_filtered), "\n"; } @@ -822,6 +823,13 @@ sub filter_units { print STDERR "setting up tmpfiles\n"; system("$new_systemd/bin/systemd-tmpfiles", "--create", "--remove", "--exclude-prefix=/dev") == 0 or $res = 3; +# We need to start nscd before any other service, since they might need +# to resolve users/groups only exposed by nss modules (i.e. DynamicUser via nss_systemd) +if ($start_nscd) { + print STDERR "starting nscd\n"; + system("@systemd@/bin/systemctl", "start", "nscd.service") == 0 or $res = 4; +} + # Before reloading we need to ensure that the units are still active. They may have been # deactivated because one of their requirements got stopped. If they are inactive # but should have been reloaded, the user probably expects them to be started.