]> git.ipfire.org Git - thirdparty/glibc.git/blob - nss/nss_test.h
[powerpc] No need to enter "Ignore Exceptions Mode"
[thirdparty/glibc.git] / nss / nss_test.h
1 /* Common code for NSS test cases.
2 Copyright (C) 2017-2019 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
4
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.
9
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.
14
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/>. */
18
19
20 /* There are two (or more) NSS test modules named nss_test1,
21 nss_test2, etc. Each one will call a function IN THE TEST CASE
22 called _nss_test1_init_hook(test_tables *) (or _nss_test2_*, etc).
23
24 In your copy of the hook function, you may change the *_table
25 pointers in the passed struct to point to static tables in your
26 test case, and the test modules will use that table instead.
27
28 Your tables MUST end with an entry that has a *_LAST() macro.
29 Use the *_ISLAST() macro to test for end of list.
30
31 Use __nss_configure_lookup("passwd", "test1 test2") (for example) to
32 configure NSS to use the test modules. */
33
34 #include <pwd.h>
35 #include <grp.h>
36
37 typedef struct test_tables {
38 struct passwd *pwd_table;
39 struct group *grp_table;
40 } test_tables;
41
42 extern void _nss_test1_init_hook (test_tables *) __attribute__((weak));
43 extern void _nss_test2_init_hook (test_tables *) __attribute__((weak));
44
45 #define PWD_LAST() { .pw_name = NULL, .pw_uid = 0 }
46 #define GRP_LAST() { .gr_name = NULL, .gr_gid = 0 }
47
48 #define PWD_ISLAST(p) ((p)->pw_name == NULL && (p)->pw_uid == 0)
49 #define GRP_ISLAST(g) ((g)->gr_name == NULL && (g)->gr_gid == 0)
50
51 /* Macros to fill in the tables easily. */
52
53 /* Note that the "unparameterized" fields are not magic; they're just
54 arbitrary values. Tests which need to verify those fields should
55 fill them in explicitly. */
56
57 #define PWD(u) \
58 { .pw_name = (char *) "name" #u, .pw_passwd = (char *) "*", .pw_uid = u, \
59 .pw_gid = 100, .pw_gecos = (char *) "*", .pw_dir = (char *) "*", \
60 .pw_shell = (char *) "*" }
61
62 #define PWD_N(u,n) \
63 { .pw_name = (char *) n, .pw_passwd = (char *) "*", .pw_uid = u, \
64 .pw_gid = 100, .pw_gecos = (char *) "*", .pw_dir = (char *) "*", \
65 .pw_shell = (char *) "*" }
66
67 #define GRP(u) \
68 { .gr_name = (char *) "name" #u, .gr_passwd = (char *) "*", .gr_gid = u, \
69 .gr_mem = (char **) group_##u }
70
71 #define GRP_N(u,n,m) \
72 { .gr_name = (char *) n, .gr_passwd = (char *) "*", .gr_gid = u, \
73 .gr_mem = (char **) m }
74
75 /*------------------------------------------------------------*/
76
77 /* Helper functions for testing passwd entries. Call
78 compare_passwds() passing a test index, the passwd entry you got,
79 and the expected passwd entry. The function will return the number
80 of mismatches, or zero of the two records are the same. */
81
82 static void __attribute__((used))
83 print_passwd (struct passwd *p)
84 {
85 printf (" passwd %u.%s (%s) :", p->pw_uid, p->pw_name, p->pw_passwd);
86 printf (" %u, %s, %s, %s\n", p->pw_gid, p->pw_gecos, p->pw_dir, p->pw_shell);
87 printf ("\n");
88 }
89
90 static int __attribute__((used))
91 compare_passwd_field (int i, struct passwd *p, const char *got,
92 const char *exp, const char *name)
93 {
94 /* Does the entry have a value? */
95 if (got == NULL)
96 {
97 printf ("[%d] passwd %s for %u.%s was (null)\n",
98 i, name,
99 p->pw_uid, p->pw_name);
100 return 1;
101 }
102 /* Does the entry have an unexpected name? */
103 else if (exp == NULL)
104 {
105 printf ("[%d] passwd %s for %u.(null) was %s\n",
106 i, name,
107 p->pw_uid, got);
108 return 1;
109 }
110 /* And is it correct? */
111 else if (got && strcmp (got, exp) != 0)
112 {
113 printf("[%d] passwd entry %u.%s had %s \"%s\" (expected \"%s\") \n",
114 i,
115 p->pw_uid, p->pw_name, name,
116 got, exp);
117 return 1;
118 }
119 return 0;
120 }
121
122 #define COMPARE_PWD_FIELD(f) \
123 retval += compare_passwd_field (i, e, p->f, e->f, #f)
124
125 /* Compare passwd to expected passwd, return number of "problems".
126 "I" is the index into the testcase data. */
127 static int __attribute__((used))
128 compare_passwds (int i, struct passwd *p, struct passwd *e)
129 {
130 int retval = 0;
131
132 /* Did we get the expected uid? */
133 if (p->pw_uid != e->pw_uid)
134 {
135 printf("[%d] passwd entry %u.%s had uid %u\n", i,
136 e->pw_uid, e->pw_name,
137 p->pw_uid);
138 ++retval;
139 }
140
141 /* Did we get the expected gid? */
142 if (p->pw_gid != e->pw_gid)
143 {
144 printf("[%d] passwd entry %u.%s had gid %u (expected %u)\n", i,
145 e->pw_uid, e->pw_name,
146 p->pw_gid, e->pw_gid);
147 ++retval;
148 }
149
150 COMPARE_PWD_FIELD (pw_name);
151 COMPARE_PWD_FIELD (pw_passwd);
152 COMPARE_PWD_FIELD (pw_gecos);
153 COMPARE_PWD_FIELD (pw_dir);
154 COMPARE_PWD_FIELD (pw_shell);
155
156 if (retval > 0)
157 {
158 /* Left in for debugging later, if needed. */
159 print_passwd (p);
160 print_passwd (e);
161 }
162
163 return retval;
164 }
165
166 /*------------------------------------------------------------*/
167
168 /* Helpers for checking group entries. See passwd helper comment
169 above for details. */
170
171 static void __attribute__((used))
172 print_group (struct group *g)
173 {
174 int j;
175
176 printf (" group %u.%s (%s) :", g->gr_gid, g->gr_name, g->gr_passwd);
177 if (g->gr_mem)
178 for (j=0; g->gr_mem[j]; j++)
179 printf ("%s%s", j==0 ? " " : ", ", g->gr_mem[j]);
180 printf ("\n");
181 }
182
183 /* Compare group to expected group, return number of "problems". "I"
184 is the index into the testcase data. */
185 static int __attribute__((used))
186 compare_groups (int i, struct group *g, struct group *e)
187 {
188 int j;
189 int retval = 0;
190
191 /* Did we get the expected gid? */
192 if (g->gr_gid != e->gr_gid)
193 {
194 printf("[%d] group entry %u.%s had gid %u\n", i,
195 e->gr_gid, e->gr_name,
196 g->gr_gid);
197 ++retval;
198 }
199
200 /* Does the entry have a name? */
201 if (g->gr_name == NULL)
202 {
203 printf ("[%d] group name for %u.%s was (null)\n", i,
204 e->gr_gid, e->gr_name);
205 ++retval;
206 }
207 /* Does the entry have an unexpected name? */
208 else if (e->gr_name == NULL)
209 {
210 printf ("[%d] group name for %u.(null) was %s\n", i,
211 e->gr_gid, g->gr_name);
212 ++retval;
213 }
214 /* And is it correct? */
215 else if (strcmp (g->gr_name, e->gr_name) != 0)
216 {
217 printf("[%d] group entry %u.%s had name \"%s\"\n", i,
218 e->gr_gid, e->gr_name,
219 g->gr_name);
220 ++retval;
221 }
222
223 /* Does the entry have a password? */
224 if (g->gr_passwd == NULL && e->gr_passwd != NULL)
225 {
226 printf ("[%d] group password for %u.%s was NULL\n", i,
227 e->gr_gid, e->gr_name);
228 ++retval;
229 }
230 else if (g->gr_passwd != NULL && e->gr_passwd == NULL)
231 {
232 printf ("[%d] group password for %u.%s was not NULL\n", i,
233 e->gr_gid, e->gr_name);
234 ++retval;
235 }
236 /* And is it correct? */
237 else if (g->gr_passwd && strcmp (g->gr_passwd, e->gr_passwd) != 0)
238 {
239 printf("[%d] group entry %u.%s had password \"%s\" (not \"%s\")\n", i,
240 e->gr_gid, e->gr_name,
241 g->gr_passwd, e->gr_passwd);
242 ++retval;
243 }
244
245 /* Now compare group members... */
246
247 if (e->gr_mem != NULL && g->gr_mem == NULL)
248 {
249 printf("[%d] group entry %u.%s missing member list\n", i,
250 e->gr_gid, e->gr_name);
251 ++retval;
252 }
253 else if (e->gr_mem == NULL && g->gr_mem != NULL)
254 {
255 printf("[%d] group entry %u.%s has unexpected member list\n", i,
256 e->gr_gid, e->gr_name);
257 ++retval;
258 }
259 else if (e->gr_mem == NULL && g->gr_mem == NULL)
260 {
261 /* This case is OK. */
262 }
263 else
264 {
265 /* Compare two existing lists. */
266 j = 0;
267 for (;;)
268 {
269 if (g->gr_mem[j] == NULL && e->gr_mem[j] == NULL)
270 {
271 /* Matching end-of-lists. */
272 break;
273 }
274 if (g->gr_mem[j] == NULL)
275 {
276 printf ("[%d] group member list for %u.%s is too short.\n", i,
277 e->gr_gid, e->gr_name);
278 ++retval;
279 break;
280 }
281 if (e->gr_mem[j] == NULL)
282 {
283 printf ("[%d] group member list for %u.%s is too long.\n", i,
284 e->gr_gid, e->gr_name);
285 ++retval;
286 break;
287 }
288 if (strcmp (g->gr_mem[j], e->gr_mem[j]) != 0)
289 {
290 printf ("[%d] group member list for %u.%s differs: %s vs %s.\n", i,
291 e->gr_gid, e->gr_name,
292 e->gr_mem[j], g->gr_mem[j]);
293 ++retval;
294 }
295
296 j++;
297 }
298 }
299
300 if (retval > 0)
301 {
302 /* Left in for debugging later, if needed. */
303 print_group (g);
304 print_group (e);
305 }
306
307 return retval;
308 }