1 /* Test that nsswitch.conf reloading actually works.
2 Copyright (C) 2020-2024 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library; if not, see
17 <https://www.gnu.org/licenses/>. */
23 #include <sys/types.h>
27 #include <support/support.h>
28 #include <support/check.h>
32 /* Size of buffers used by *_r functions. */
33 #define TESTBUFLEN 4096
35 static struct passwd pwd_table_1
[] = {
44 static const char *hostaddr_5
[] =
46 "ABCd", "ABCD", "ABC4", NULL
49 static const char *hostaddr_15
[] =
54 static const char *hostaddr_25
[] =
60 static struct hostent host_table_1
[] = {
68 _nss_test1_init_hook(test_tables
*t
)
70 t
->pwd_table
= pwd_table_1
;
71 t
->host_table
= host_table_1
;
74 /* The first of these must not appear in pwd_table_1. */
75 static struct passwd pwd_table_2
[] = {
82 static const char *hostaddr_6
[] =
87 static const char *hostaddr_16
[] =
92 static const char *hostaddr_26
[] =
97 static struct hostent host_table_2
[] = {
105 _nss_test2_init_hook(test_tables
*t
)
107 t
->pwd_table
= pwd_table_2
;
108 t
->host_table
= host_table_2
;
112 must_be_tests (struct passwd
*pt
, struct hostent
*ht
)
118 for (i
= 0; !PWD_ISLAST (&pt
[i
]); ++i
)
120 p
= getpwuid (pt
[i
].pw_uid
);
121 TEST_VERIFY (p
!= NULL
);
124 TEST_COMPARE_STRING (p
->pw_name
, pt
[i
].pw_name
);
129 for (i
= 0; !PWD_ISLAST (&pt
[i
]); ++i
)
132 TEST_VERIFY (p
!= NULL
);
135 TEST_COMPARE_STRING (p
->pw_name
, pt
[i
].pw_name
);
136 TEST_COMPARE (p
->pw_uid
, pt
[i
].pw_uid
);
141 for (i
= 0; !HOST_ISLAST (&ht
[i
]); ++i
)
143 h
= gethostbyname (ht
[i
].h_name
);
144 TEST_VERIFY (h
!= NULL
);
147 TEST_COMPARE_STRING (h
->h_name
, ht
[i
].h_name
);
148 TEST_COMPARE (h
->h_addrtype
, AF_INET
);
149 TEST_VERIFY (h
->h_addr_list
[0] != NULL
);
150 if (h
->h_addr_list
[0] != NULL
)
151 TEST_COMPARE_BLOB (h
->h_addr_list
[0], h
->h_length
,
152 ht
[i
].h_addr_list
[0], ht
[i
].h_length
);
156 for (i
= 0; !HOST_ISLAST (&ht
[i
]); ++i
)
158 struct hostent r
, *rp
;
159 char buf
[TESTBUFLEN
];
162 res
= gethostbyname2_r (ht
[i
].h_name
, AF_INET
,
163 &r
, buf
, TESTBUFLEN
, &rp
, &herrno
);
164 TEST_COMPARE (res
, 0);
167 TEST_COMPARE_STRING (r
.h_name
, ht
[i
].h_name
);
168 TEST_COMPARE (r
.h_addrtype
, AF_INET
);
169 TEST_VERIFY (r
.h_addr_list
[0] != NULL
);
170 if (r
.h_addr_list
[0] != NULL
)
171 TEST_COMPARE_BLOB (r
.h_addr_list
[0], r
.h_length
,
172 ht
[i
].h_addr_list
[0], ht
[i
].h_length
);
176 for (i
= 0; !HOST_ISLAST (&ht
[i
]); ++i
)
178 h
= gethostbyaddr (ht
[i
].h_addr
, 4, AF_INET
);
179 TEST_VERIFY (h
!= NULL
);
182 TEST_COMPARE_STRING (h
->h_name
, ht
[i
].h_name
);
183 TEST_VERIFY (h
->h_addr_list
[0] != NULL
);
184 if (h
->h_addr_list
[0] != NULL
)
185 TEST_COMPARE_BLOB (h
->h_addr_list
[0], h
->h_length
,
186 ht
[i
].h_addr_list
[0], ht
[i
].h_length
);
192 for (i
= 0; !HOST_ISLAST (&ht
[i
]); ++i
)
195 struct addrinfo hint
;
198 memset (&hint
, 0, sizeof (hint
));
199 hint
.ai_family
= AF_INET
;
200 hint
.ai_socktype
= SOCK_STREAM
;
201 hint
.ai_protocol
= 0;
205 res
= getaddrinfo (ht
[i
].h_name
, NULL
, &hint
, &ap
);
206 TEST_COMPARE (res
, 0);
207 TEST_VERIFY (ap
!= NULL
);
208 if (res
== 0 && ap
!= NULL
)
210 j
= 0; /* which address in the list */
213 TEST_COMPARE (ap
->ai_family
, AF_INET
);
215 struct sockaddr_in
*in
= (struct sockaddr_in
*)ap
->ai_addr
;
216 unsigned char *up
= (unsigned char *)&in
->sin_addr
;
218 TEST_COMPARE_BLOB (up
, 4, ht
[i
].h_addr_list
[j
], 4);
228 for (i
= 0; !HOST_ISLAST (&ht
[i
]); ++i
)
230 struct sockaddr_in addr
;
232 char host_buf
[NI_MAXHOST
];
234 memset (&addr
, 0, sizeof (addr
));
235 addr
.sin_family
= AF_INET
;
237 memcpy (& addr
.sin_addr
, ht
[i
].h_addr_list
[0], 4);
239 res
= getnameinfo ((struct sockaddr
*) &addr
, sizeof(addr
),
240 host_buf
, sizeof(host_buf
),
243 TEST_COMPARE (res
, 0);
245 TEST_VERIFY (strcmp (ht
[i
].h_name
, host_buf
) == 0);
247 printf ("error %s\n", gai_strerror (res
));
256 must_be_tests (pwd_table_1
, host_table_1
);
257 p
= getpwnam("name5");
258 TEST_VERIFY (p
== NULL
);
266 must_be_tests (pwd_table_2
, host_table_2
);
267 p
= getpwnam("name100");
268 TEST_VERIFY (p
== NULL
);
272 xrename (const char *a
, const char *b
)
274 int i
= rename (a
, b
);
276 FAIL_EXIT1 ("rename(%s,%s) failed: %s\n", a
, b
, strerror(errno
));
279 /* If the actions change while in the midst of doing a series of
280 lookups, make sure they're consistent. */
282 test_cross_switch_consistency (void)
287 /* We start by initiating a set/get/end loop on conf1. */
289 for (i
= 0; !PWD_ISLAST (&pwd_table_1
[i
]); ++i
)
292 TEST_VERIFY (p
!= NULL
);
295 TEST_COMPARE_STRING (p
->pw_name
, pwd_table_1
[i
].pw_name
);
296 TEST_COMPARE (p
->pw_uid
, pwd_table_1
[i
].pw_uid
);
299 /* After the first lookup, switch to conf2 and verify */
302 xrename ("/etc/nsswitch.conf", "/etc/nsswitch.conf1");
303 xrename ("/etc/nsswitch.conf2", "/etc/nsswitch.conf");
305 p
= getpwnam (pwd_table_2
[0].pw_name
);
306 TEST_COMPARE (p
->pw_uid
, pwd_table_2
[0].pw_uid
);
309 /* But the original loop should still be on conf1. */
313 /* Make sure the set/get/end loop sees conf2 now. */
315 for (i
= 0; !PWD_ISLAST (&pwd_table_2
[i
]); ++i
)
318 TEST_VERIFY (p
!= NULL
);
321 TEST_COMPARE_STRING (p
->pw_name
, pwd_table_2
[i
].pw_name
);
322 TEST_COMPARE (p
->pw_uid
, pwd_table_2
[i
].pw_uid
);
332 /* The test1 module was configured at program start. */
335 xrename ("/etc/nsswitch.conf", "/etc/nsswitch.conf1");
336 xrename ("/etc/nsswitch.conf2", "/etc/nsswitch.conf");
339 xrename ("/etc/nsswitch.conf", "/etc/nsswitch.conf2");
340 xrename ("/etc/nsswitch.conf1", "/etc/nsswitch.conf");
343 test_cross_switch_consistency ();
348 #include <support/test-driver.c>