summaryrefslogtreecommitdiffstats
path: root/nsswitch/b15464-testcase.c
blob: decb474a81eeb03042d6044268806026f0f113ca (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
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;
}