diff --git a/nixos/modules/config/nsswitch.nix b/nixos/modules/config/nsswitch.nix
index fb45664e44e12..c3e7b867a86f4 100644
--- a/nixos/modules/config/nsswitch.nix
+++ b/nixos/modules/config/nsswitch.nix
@@ -6,9 +6,6 @@ with lib;
{
options = {
-
- # NSS modules. Hacky!
- # Only works with nscd!
system.nssModules = mkOption {
type = types.listOf types.path;
internal = true;
@@ -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,14 +73,11 @@ 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.";
- }
+ # Provide configured NSS modules at a platform-specific path in /run
+ systemd.tmpfiles.rules = let
+ glibcPlatform = "${if pkgs.stdenv.hostPlatform.is64bit then "64" else "32"}-${pkgs.glibc.version}";
+ in [
+ "L+ /run/nss-modules${glibcPlatform} - - - - ${config.system.nssModules.path}"
];
# Name Service Switch configuration file. Required by the C
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..1ca8152681577
--- /dev/null
+++ b/pkgs/development/libraries/glibc/add-extra-module-load-path.patch
@@ -0,0 +1,75 @@
+Add NSS module load path /run/nss-modules${word_size}-${glibc_version}/lib
+
+If this path is not present at runtime, the behaviour of libc is unchanged.
+
+If this path is present:
+- Don't use nscd
+- Use this load path as a fallback after paths ${glibc.out}/lib and LD_LIBRARY_PATH
+
+On NixOS, this allows ABI-compatible glibc clients to directly load NSS modules
+instead of using nscd for name service requests.
+nscd has caching bugs and leaks DNS requests across network namespaces.
+
+nscd, if running, will still be used by ABI-incompatible glibc clients.
+(Such as 32-bit binaries on a 64-bit host or binaries with older glibc versions.)
+This guarantees full backwards compatibility.
+
+On non-NixOS systems, this shouldn't change behaviour, as the path
+doesn't exist there.
+
+diff --git a/nscd/nscd_helper.c b/nscd/nscd_helper.c
+index 462504d8..65cca10d 100644
+--- a/nscd/nscd_helper.c
++++ b/nscd/nscd_helper.c
+@@ -169,6 +169,12 @@ open_socket (request_type type, const char *key, size_t keylen)
+ {
+ int sock;
+
++ /* Don't use nscd when the platform-specific NixOS module load path is present */
++#include "../nss/nixos-nss-modules-path.h"
++ if (access(NIXOS_NSS_MODULES_PATH, F_OK) == 0) {
++ return -1;
++ }
++
+ sock = __socket (PF_UNIX, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0);
+ if (sock < 0)
+ return -1;
+diff --git a/nss/nixos-nss-modules-path.h b/nss/nixos-nss-modules-path.h
+new file mode 100644
+index 00000000..20a5643b
+--- /dev/null
++++ b/nss/nixos-nss-modules-path.h
+@@ -0,0 +1,3 @@
++#define STR_(x) #x
++#define STR(x) STR_(x)
++#define NIXOS_NSS_MODULES_PATH "/run/nss-modules" STR(__WORDSIZE) "-" STR(__GLIBC__) "." STR(__GLIBC_MINOR__) "/lib/"
+diff --git a/nss/nss_module.c b/nss/nss_module.c
+index 6c5f341f..f5296507 100644
+--- a/nss/nss_module.c
++++ b/nss/nss_module.c
+@@ -133,6 +133,25 @@ 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) {
++
++#include "nixos-nss-modules-path.h"
++ 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..28c7721aeff16 100644
--- a/pkgs/development/libraries/glibc/common.nix
+++ b/pkgs/development/libraries/glibc/common.nix
@@ -120,6 +120,8 @@ stdenv.mkDerivation ({
})
./fix-x64-abi.patch
+
+ ./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;