diff --git a/nsswitch/b15464-testcase.c b/nsswitch/b15464-testcase.c
new file mode 100644
index 00000000000..decb474a81e
--- /dev/null
+++ b/nsswitch/b15464-testcase.c
@@ -0,0 +1,77 @@
+#include "replace.h"
+#include "system/wait.h"
+#include "system/threads.h"
+#include <assert.h>
+
+int main(int argc, const char *argv[])
+{
+	pid_t pid;
+	int wstatus;
+	pthread_key_t k1;
+	pthread_key_t k2;
+	pthread_key_t k3;
+	char *val = NULL;
+	const char *nss_winbind = (argc >= 2 ? argv[1] : "bin/plugins/libnss_winbind.so.2");
+	void *nss_winbind_handle = NULL;
+	union {
+		int (*fn)(void);
+		void *symbol;
+	} nss_winbind_endpwent = { .symbol = NULL, };
+
+	/*
+	 * load and invoke something simple like
+	 * _nss_winbind_endpwent in order to
+	 * get the libnss_winbind internal going
+	 */
+	nss_winbind_handle = dlopen(nss_winbind, RTLD_NOW);
+	printf("%d: nss_winbind[%s] nss_winbind_handle[%p]\n",
+	       getpid(), nss_winbind, nss_winbind_handle);
+	assert(nss_winbind_handle != NULL);
+
+	nss_winbind_endpwent.symbol = dlsym(nss_winbind_handle,
+					    "_nss_winbind_endpwent");
+	printf("%d: nss_winbind_handle[%p] _nss_winbind_endpwent[%p]\n",
+	       getpid(), nss_winbind_handle, nss_winbind_endpwent.symbol);
+	assert(nss_winbind_endpwent.symbol != NULL);
+	(void)nss_winbind_endpwent.fn();
+
+	val = malloc(1);
+	assert(val != NULL);
+
+	pthread_key_create(&k1, NULL);
+	pthread_setspecific(k1, val);
+	printf("%d: k1=%d\n", getpid(), k1);
+
+	pid = fork();
+	if (pid) {
+		free(val);
+		wait(&wstatus);
+		return WEXITSTATUS(wstatus);
+	}
+
+	pthread_key_create(&k2, NULL);
+	pthread_setspecific(k2, val);
+
+	printf("%d: Hello after fork, k1=%d, k2=%d\n", getpid(), k1, k2);
+
+	pid = fork();
+
+	if (pid) {
+		free(val);
+		wait(&wstatus);
+		return WEXITSTATUS(wstatus);
+	}
+
+	pthread_key_create(&k3, NULL);
+	pthread_setspecific(k3, val);
+
+	printf("%d: Hello after fork2, k1=%d, k2=%d, k3=%d\n", getpid(), k1, k2, k3);
+
+	if (k1 == k2 || k2 == k3) {
+		printf("%d: FAIL inconsistent keys\n", getpid());
+		return 1;
+	}
+
+	printf("%d: OK consistent keys\n", getpid());
+	return 0;
+}
diff --git a/nsswitch/wscript_build b/nsswitch/wscript_build
index 3247b6c2b7c..4e62bb4c946 100644
--- a/nsswitch/wscript_build
+++ b/nsswitch/wscript_build
@@ -15,6 +15,11 @@ if bld.CONFIG_SET('HAVE_PTHREAD'):
 		     deps='wbclient pthread',
 		     for_selftest=True
 		     )
+    bld.SAMBA_BINARY('b15464-testcase',
+		     source='b15464-testcase.c',
+		     deps='replace pthread dl',
+		     for_selftest=True
+		     )
 
 # The nss_wrapper code relies strictly on the linux implementation and
 # name, so compile but do not install a copy under this name.
diff --git a/selftest/knownfail.d/b15464_testcase b/selftest/knownfail.d/b15464_testcase
new file mode 100644
index 00000000000..94dd7db7c2a
--- /dev/null
+++ b/selftest/knownfail.d/b15464_testcase
@@ -0,0 +1 @@
+^b15464_testcase.run.b15464-testcase
diff --git a/source3/selftest/tests.py b/source3/selftest/tests.py
index 9d77c49ed48..fa51f7fdcbd 100755
--- a/source3/selftest/tests.py
+++ b/source3/selftest/tests.py
@@ -67,6 +67,8 @@ except KeyError:
     samba4bindir = bindir()
     config_h = os.path.join(samba4bindir, "default/include/config.h")
 
+bbdir = os.path.join(srcdir(), "testprogs/blackbox")
+
 # check available features
 config_hash = dict()
 f = open(config_h, 'r')
@@ -958,6 +960,10 @@ if with_pthreadpool:
                   [os.path.join(samba3srcdir,
                                 "script/tests/test_libwbclient_threads.sh"),
                    "$DOMAIN", "$DC_USERNAME"])
+    plantestsuite("b15464_testcase", "none",
+                  [os.path.join(bbdir, "b15464-testcase.sh"),
+                   binpath("b15464-testcase"),
+                   binpath("plugins/libnss_winbind.so.2")])
 
 plantestsuite("samba3.test_nfs4_acl", "none",
               [os.path.join(bindir(), "test_nfs4_acls"),
diff --git a/testprogs/blackbox/b15464-testcase.sh b/testprogs/blackbox/b15464-testcase.sh
new file mode 100755
index 00000000000..b0c88260d4c
--- /dev/null
+++ b/testprogs/blackbox/b15464-testcase.sh
@@ -0,0 +1,21 @@
+#!/bin/sh
+# Blackbox wrapper for bug 15464
+# Copyright (C) 2023 Stefan Metzmacher
+
+if [ $# -lt 2 ]; then
+	cat <<EOF
+Usage: b15464-testcase.sh B15464_TESTCASE LIBNSS_WINBIND
+EOF
+	exit 1
+fi
+
+b15464_testcase=$1
+libnss_winbind=$2
+shift 2
+failed=0
+
+. $(dirname $0)/subunit.sh
+
+testit "run b15464-testcase" $VALGRIND $b15464_testcase $libnss_winbind || failed=$(expr $failed + 1)
+
+testok $0 $failed