diff --git a/nixos/modules/config/nsswitch.nix b/nixos/modules/config/nsswitch.nix
index fb45664e44e12..830a111130d98 100644
--- a/nixos/modules/config/nsswitch.nix
+++ b/nixos/modules/config/nsswitch.nix
@@ -6,11 +6,8 @@ with lib;
{
options = {
-
- # NSS modules. Hacky!
- # Only works with nscd!
system.nssModules = mkOption {
- type = types.listOf types.path;
+ type = types.listOf types.package;
internal = true;
default = [];
description = ''
@@ -33,10 +30,6 @@ with lib;
type = types.listOf types.str;
description = ''
List of passwd entries to configure in /etc/nsswitch.conf.
-
- Note that "files" is always prepended while "systemd" is appended if nscd is enabled.
-
- This option only takes effect if nscd is enabled.
'';
default = [];
};
@@ -45,10 +38,6 @@ with lib;
type = types.listOf types.str;
description = ''
List of group entries to configure in /etc/nsswitch.conf.
-
- Note that "files" is always prepended while "systemd" is appended if nscd is enabled.
-
- This option only takes effect if nscd is enabled.
'';
default = [];
};
@@ -57,10 +46,6 @@ with lib;
type = types.listOf types.str;
description = ''
List of shadow entries to configure in /etc/nsswitch.conf.
-
- Note that "files" is always prepended.
-
- This option only takes effect if nscd is enabled.
'';
default = [];
};
@@ -69,10 +54,6 @@ with lib;
type = types.listOf types.str;
description = ''
List of hosts entries to configure in /etc/nsswitch.conf.
-
- Note that "files" is always prepended, and "dns" and "myhostname" are always appended.
-
- This option only takes effect if nscd is enabled.
'';
default = [];
};
@@ -81,10 +62,6 @@ with lib;
type = types.listOf types.str;
description = ''
List of services entries to configure in /etc/nsswitch.conf.
-
- Note that "files" is always prepended.
-
- This option only takes effect if nscd is enabled.
'';
default = [];
};
@@ -96,16 +73,31 @@ with lib;
];
config = {
- assertions = [
- {
- # Prevent users from disabling nscd, with nssModules being set.
- # If disabling nscd is really necessary, it's still possible to opt out
- # by forcing config.system.nssModules to [].
- assertion = config.system.nssModules.path != "" -> config.services.nscd.enable;
- message = "Loading NSS modules from system.nssModules (${config.system.nssModules.path}), requires services.nscd.enable being set to true.";
+ assertions = let
+ systemGlibc = pkgs.stdenv.glibc.outPath;
+ incompatibleModules = builtins.filter (module: module.stdenv.glibc.outPath != systemGlibc)
+ config.system.nssModules.list;
+ in [
+ { assertion = (incompatibleModules == []);
+ message = ''
+ The following NSS modules don't use the system glibc derivation.
+ They can fail due to ABI incompatibilities. Please remove them:
+ ${concatMapStringsSep "\n" (builtins.getAttr "name") incompatibleModules}
+ '';
}
];
+ # Provide NSS modules at a glibc-specific path in /run
+ # See ../../../pkgs/development/libraries/glibc/add-extra-module-load-path.patch
+ # for further details.
+ systemd.tmpfiles.rules = let
+ prefixLen = builtins.stringLength builtins.storeDir + 1;
+ hashLen = 32;
+ glibcStorePathHash = builtins.substring prefixLen hashLen pkgs.glibc.outPath;
+ in [
+ "L+ /run/nss-modules-${glibcStorePathHash} - - - - ${config.system.nssModules.path}"
+ ];
+
# Name Service Switch configuration file. Required by the C
# library.
environment.etc."nsswitch.conf".text = ''
diff --git a/nixos/modules/services/network-filesystems/samba.nix b/nixos/modules/services/network-filesystems/samba.nix
index 78ea245cb3519..1154b21fdad51 100644
--- a/nixos/modules/services/network-filesystems/samba.nix
+++ b/nixos/modules/services/network-filesystems/samba.nix
@@ -33,9 +33,6 @@ let
${smbToString (map shareConfig (attrNames cfg.shares))}
'');
- # This may include nss_ldap, needed for samba if it has to use ldap.
- nssModulesPath = config.system.nssModules.path;
-
daemonService = appName: args:
{ description = "Samba Service Daemon ${appName}";
@@ -44,7 +41,6 @@ let
partOf = [ "samba.target" ];
environment = {
- LD_LIBRARY_PATH = nssModulesPath;
LOCALE_ARCHIVE = "/run/current-system/sw/lib/locale/locale-archive";
};
diff --git a/nixos/modules/services/networking/avahi-daemon.nix b/nixos/modules/services/networking/avahi-daemon.nix
index 020a817f25961..c58202c1427fb 100644
--- a/nixos/modules/services/networking/avahi-daemon.nix
+++ b/nixos/modules/services/networking/avahi-daemon.nix
@@ -264,10 +264,6 @@ in
wantedBy = [ "multi-user.target" ];
requires = [ "avahi-daemon.socket" ];
- # Make NSS modules visible so that `avahi_nss_support ()' can
- # return a sensible value.
- environment.LD_LIBRARY_PATH = config.system.nssModules.path;
-
path = [ pkgs.coreutils pkgs.avahi ];
serviceConfig = {
diff --git a/nixos/modules/services/networking/ssh/lshd.nix b/nixos/modules/services/networking/ssh/lshd.nix
index 862ff7df05407..e1eba3a7a8f07 100644
--- a/nixos/modules/services/networking/ssh/lshd.nix
+++ b/nixos/modules/services/networking/ssh/lshd.nix
@@ -137,10 +137,6 @@ in
wantedBy = [ "multi-user.target" ];
- environment = {
- LD_LIBRARY_PATH = config.system.nssModules.path;
- };
-
preStart = ''
test -d /etc/lsh || mkdir -m 0755 -p /etc/lsh
test -d /var/spool/lsh || mkdir -m 0755 -p /var/spool/lsh
diff --git a/nixos/modules/services/networking/ssh/sshd.nix b/nixos/modules/services/networking/ssh/sshd.nix
index 225aee5160503..89adc40379394 100644
--- a/nixos/modules/services/networking/ssh/sshd.nix
+++ b/nixos/modules/services/networking/ssh/sshd.nix
@@ -24,8 +24,6 @@ let
cfg = config.services.openssh;
cfgc = config.programs.ssh;
- nssModulesPath = config.system.nssModules.path;
-
userOptions = {
options.openssh.authorizedKeys = {
@@ -421,7 +419,6 @@ in
after = [ "network.target" ];
stopIfChanged = false;
path = [ cfgc.package pkgs.gawk ];
- environment.LD_LIBRARY_PATH = nssModulesPath;
restartTriggers = optionals (!cfg.startWhenNeeded) [
config.environment.etc."ssh/sshd_config".source
diff --git a/nixos/modules/services/system/dbus.nix b/nixos/modules/services/system/dbus.nix
index d4cacb85694b9..f7ab64630610b 100644
--- a/nixos/modules/services/system/dbus.nix
+++ b/nixos/modules/services/system/dbus.nix
@@ -122,7 +122,6 @@ in
# Don't restart dbus-daemon. Bad things tend to happen if we do.
reloadIfChanged = true;
restartTriggers = [ configDir ];
- environment = { LD_LIBRARY_PATH = config.system.nssModules.path; };
};
systemd.user = {
diff --git a/nixos/modules/services/system/nscd.conf b/nixos/modules/services/system/nscd.conf
index 722b883ba420b..eb9c48ded1266 100644
--- a/nixos/modules/services/system/nscd.conf
+++ b/nixos/modules/services/system/nscd.conf
@@ -1,11 +1,3 @@
-# We basically use nscd as a proxy for forwarding nss requests to appropriate
-# nss modules, as we run nscd with LD_LIBRARY_PATH set to the directory
-# containing all such modules
-# Note that we can not use `enable-cache no` As this will actually cause nscd
-# to just reject the nss requests it receives, which then causes glibc to
-# fallback to trying to handle the request by itself. Which won't work as glibc
-# is not aware of the path in which the nss modules live. As a workaround, we
-# have `enable-cache yes` with an explicit ttl of 0
server-user nscd
enable-cache passwd yes
diff --git a/nixos/modules/services/system/nscd.nix b/nixos/modules/services/system/nscd.nix
index 7d05acfc14b87..1d7229d110753 100644
--- a/nixos/modules/services/system/nscd.nix
+++ b/nixos/modules/services/system/nscd.nix
@@ -4,7 +4,6 @@ with lib;
let
- nssModulesPath = config.system.nssModules.path;
cfg = config.services.nscd;
nscd = if pkgs.stdenv.hostPlatform.libc == "glibc"
@@ -26,8 +25,6 @@ in
default = true;
description = ''
Whether to enable the Name Service Cache Daemon.
- Disabling this is strongly discouraged, as this effectively disables NSS Lookups
- from all non-glibc NSS modules, including the ones provided by systemd.
'';
};
@@ -53,8 +50,6 @@ in
wantedBy = [ "nss-lookup.target" "nss-user-lookup.target" ];
- environment = { LD_LIBRARY_PATH = nssModulesPath; };
-
restartTriggers = [
config.environment.etc.hosts.source
config.environment.etc."nsswitch.conf".source
diff --git a/nixos/modules/system/boot/resolved.nix b/nixos/modules/system/boot/resolved.nix
index a6fc07da0abbf..36f9302a8e86a 100644
--- a/nixos/modules/system/boot/resolved.nix
+++ b/nixos/modules/system/boot/resolved.nix
@@ -138,7 +138,6 @@ in
users.users.systemd-resolve.group = "systemd-resolve";
- # add resolve to nss hosts database if enabled and nscd enabled
# system.nssModules is configured in nixos/modules/system/boot/systemd.nix
# added with order 501 to allow modules to go before with mkBefore
system.nssDatabases.hosts = (mkOrder 501 ["resolve [!UNAVAIL=return]"]);
diff --git a/nixos/tests/resolv.nix b/nixos/tests/resolv.nix
index f0aa7e42aaf35..5ff9491036bdd 100644
--- a/nixos/tests/resolv.nix
+++ b/nixos/tests/resolv.nix
@@ -29,7 +29,6 @@ import ./make-test-python.nix ({ pkgs, ... } : {
start_all()
- resolv.wait_for_unit("nscd")
ipv4 = ["192.0.2.1", "192.0.2.2"]
ipv6 = ["2001:db8::2:1", "2001:db8::2:2"]
diff --git a/pkgs/development/libraries/glibc/add-extra-module-load-path.patch b/pkgs/development/libraries/glibc/add-extra-module-load-path.patch
new file mode 100644
index 0000000000000..aee96449e755a
--- /dev/null
+++ b/pkgs/development/libraries/glibc/add-extra-module-load-path.patch
@@ -0,0 +1,43 @@
+Add NSS module load path /run/nss-modules-${glibc-store-path-hash} as a
+fallback. Previously, glibc only looked for NSS modules in ${glibc.out}/lib and
+LD_LIBRARY_PATH.
+
+When this path is provided by NixOS, glibc binaries can be run without nscd.
+nscd has caching bugs and leaks DNS requests across network namespaces.
+Also, it's no longer required to set LD_LIBRARY_PATH for NSS modules that can't
+be proxied by nscd.
+
+The module load path is only used by binaries that use the same glibc
+derivation as the NSS modules. Loading different glibc instances into a
+single process would lead to failures due to ABI incompatibilities.
+
+On non-NixOS systems, this patch doesn't change behaviour, as the path
+doesn't exist there.
+diff --git a/nss/nss_module.c b/nss/nss_module.c
+index 6c5f341f..a9975dd6 100644
+--- a/nss/nss_module.c
++++ b/nss/nss_module.c
+@@ -133,6 +133,23 @@ module_load (struct nss_module *module)
+ return false;
+
+ handle = __libc_dlopen (shlib_name);
++
++ /* After loading from the default locations, try loading from
++ the NixOS module load path. */
++ if (handle == NULL) {
++ const char nix_nss_path[] = "@NIXOS_NSS_MODULES_PATH@";
++ char shlib_path[1024];
++ size_t nix_nss_path_len = sizeof(nix_nss_path) - 1;
++ size_t shlib_name_len = strlen(shlib_name);
++ size_t shlib_path_len = nix_nss_path_len + shlib_name_len;
++
++ if (shlib_path_len < sizeof(shlib_path)) {
++ memcpy(&shlib_path[0], nix_nss_path, nix_nss_path_len);
++ memcpy(&shlib_path[nix_nss_path_len], shlib_name, shlib_name_len + 1);
++ handle = __libc_dlopen(shlib_path);
++ }
++ }
++
+ free (shlib_name);
+ }
+
diff --git a/pkgs/development/libraries/glibc/common.nix b/pkgs/development/libraries/glibc/common.nix
index e651a8effac99..ea9acfc25a5e5 100644
--- a/pkgs/development/libraries/glibc/common.nix
+++ b/pkgs/development/libraries/glibc/common.nix
@@ -120,6 +120,9 @@ stdenv.mkDerivation ({
})
./fix-x64-abi.patch
+
+ # This patch requires additional processing in postPatch
+ ./add-extra-module-load-path.patch
]
++ lib.optional stdenv.hostPlatform.isMusl ./fix-rpc-types-musl-conflicts.patch
++ lib.optional stdenv.buildPlatform.isDarwin ./darwin-cross-build.patch;
@@ -133,6 +136,12 @@ stdenv.mkDerivation ({
# nscd needs libgcc, and we don't want it dynamically linked
# because we don't want it to depend on bootstrap-tools libs.
echo "LDFLAGS-nscd += -static-libgcc" >> nscd/Makefile
+
+ # Required by ./add-extra-module-load-path.patch
+ [[ $out =~ /nix/store/([^-]+) ]]
+ storePathHash=''${BASH_REMATCH[1]}
+ nssModulesPath=/run/nss-modules-$storePathHash/lib/
+ sed -i "s|@NIXOS_NSS_MODULES_PATH@|$nssModulesPath|g" nss/nss_module.c
''
# FIXME: find a solution for infinite recursion in cross builds.
# For now it's hopefully acceptable that IDN from libc doesn't reliably work.