332b73ffd4b4b248b91f079e0f260525cbb639ae
[uid_wrapper.git] / tests / testsuite.c
1 #include "config.h"
2
3 #include <stdarg.h>
4 #include <stddef.h>
5 #include <setjmp.h>
6 #include <cmocka.h>
7
8 #include <errno.h>
9 #include <string.h>
10 #include <stdlib.h>
11 #include <stdio.h>
12 #include <sys/types.h>
13 #include <sys/stat.h>
14 #include <sys/time.h>
15 #include <unistd.h>
16
17 #include <pwd.h>
18 #include <grp.h>
19
20 #ifdef HAVE_SYS_SYSCALL_H
21 #include <sys/syscall.h>
22 #endif
23 #ifdef HAVE_SYSCALL_H
24 #include <syscall.h>
25 #endif
26
27 #define ZERO_STRUCT(x) memset((char *)&(x), 0, sizeof(x))
28 #define ARRAY_SIZE(a) (sizeof(a)/sizeof(a[0]))
29
30 static void test_uwrap_seteuid(void **state)
31 {
32         int rc;
33         uid_t u;
34
35         (void) state; /* unused */
36
37         rc = seteuid(-1);
38         assert_int_equal(rc, -1);
39
40         rc = seteuid(0);
41         assert_int_equal(rc, 0);
42
43         u = geteuid();
44 #ifdef SYS_geteuid /* not available on Solaris */
45         assert_int_equal(u, syscall(SYS_geteuid));
46 #endif
47
48         rc = setuid(42);
49         assert_int_equal(rc, 0);
50
51         u = getuid();
52         assert_int_equal(u, 42);
53 }
54
55 #ifdef HAVE_SETREUID
56 static void test_uwrap_setreuid(void **state)
57 {
58         int rc;
59         uid_t u;
60
61         (void) state; /* unused */
62
63         rc = setreuid(1, 2);
64         assert_int_equal(rc, 0);
65
66         u = getuid();
67         assert_int_equal(u, 1);
68
69         u = geteuid();
70         assert_int_equal(u, 2);
71 }
72 #endif
73
74 #ifdef HAVE_SETRESUID
75 static void test_uwrap_setresuid(void **state)
76 {
77         int rc;
78         uid_t u;
79
80         (void) state; /* unused */
81
82         rc = setresuid(1, 2, -1);
83         assert_int_equal(rc, 0);
84
85         u = getuid();
86         assert_int_equal(u, 1);
87
88         u = geteuid();
89         assert_int_equal(u, 2);
90 }
91 #endif
92
93 #ifdef HAVE_GETRESUID
94 static void test_uwrap_getresuid(void **state)
95 {
96         int rc;
97         uid_t ru, eu, su;
98
99         (void) state; /* unused */
100
101         rc = setresuid(1, 2, -1);
102         assert_int_equal(rc, 0);
103
104         ru = getuid();
105         assert_int_equal(ru, 1);
106
107         eu = geteuid();
108         assert_int_equal(eu, 2);
109
110         rc = getresuid(&ru, &eu, &su);
111         assert_int_equal(ru, 1);
112         assert_int_equal(eu, 2);
113 }
114 #endif
115
116 static void test_uwrap_setuid(void **state)
117 {
118         int rc;
119         uid_t u;
120
121         (void) state; /* unused */
122
123         rc = setuid(-1);
124         assert_int_equal(rc, -1);
125
126         rc = setuid(42);
127         assert_int_equal(rc, 0);
128
129         u = getuid();
130         assert_int_equal(u, 42);
131 }
132
133 static void test_uwrap_setegid(void **state)
134 {
135         int rc;
136         uid_t u;
137
138         (void) state; /* unused */
139
140         rc = setegid(0);
141         assert_int_equal(rc, 0);
142
143         u = getegid();
144 #ifdef SYS_getegid /* Not available on Solaris */
145         assert_int_equal(u, syscall(SYS_getegid));
146 #endif
147
148         rc = setegid(42);
149         assert_int_equal(rc, 0);
150
151         u = getegid();
152         assert_int_equal(u, 42);
153 }
154
155 #ifdef HAVE_SETREGID
156 static void test_uwrap_setregid(void **state)
157 {
158         int rc;
159         uid_t u;
160
161         (void) state; /* unused */
162
163         rc = setregid(1, 2);
164         assert_int_equal(rc, 0);
165
166         u = getgid();
167         assert_int_equal(u, 1);
168
169         u = getegid();
170         assert_int_equal(u, 2);
171 }
172 #endif
173
174 #ifdef HAVE_SETRESGID
175 static void test_uwrap_setresgid(void **state)
176 {
177         int rc;
178         uid_t u;
179
180         (void) state; /* unused */
181
182         rc = setresgid(1, 2, -1);
183         assert_int_equal(rc, 0);
184
185         u = getgid();
186         assert_int_equal(u, 1);
187
188         u = getegid();
189         assert_int_equal(u, 2);
190 }
191 #endif
192
193 static void test_uwrap_setgid(void **state)
194 {
195         int rc;
196         gid_t u;
197
198         (void) state; /* unused */
199
200         rc = setgid(-1);
201         assert_int_equal(rc, -1);
202
203         rc = setgid(42);
204         assert_int_equal(rc, 0);
205
206         u = getgid();
207         assert_int_equal(u, 42);
208 }
209
210 static void test_uwrap_syscall(void **state)
211 {
212         long int rc;
213         struct timeval tv1, tv2;
214         struct timezone tz1, tz2;
215
216         (void) state; /* unused */
217
218         rc = syscall(SYS_getpid);
219         assert_int_equal(rc, getpid());
220
221         ZERO_STRUCT(tv1);
222         ZERO_STRUCT(tv2);
223         ZERO_STRUCT(tz1);
224         ZERO_STRUCT(tz2);
225
226         rc = gettimeofday(&tv1, &tz1);
227         assert_int_equal(rc, 0);
228
229 #ifdef OSX
230         tv2.tv_sec = syscall(SYS_gettimeofday, &tv2, NULL);
231 #else
232         rc = syscall(SYS_gettimeofday, &tv2, &tz2);
233         assert_int_equal(rc, 0);
234         assert_int_equal(tz1.tz_dsttime, tz2.tz_dsttime);
235         assert_int_equal(tz1.tz_minuteswest, tz2.tz_minuteswest);
236 #endif
237
238         assert_int_equal(tv1.tv_sec, tv2.tv_sec);
239 }
240
241 static void test_uwrap_syscall_setreuid(void **state)
242 {
243         long int rc;
244         uid_t u;
245
246         (void) state; /* unused */
247
248 #if defined(SYS_setreuid)
249         rc = syscall(SYS_setreuid, -1, 0);
250 #elif defined(SYS_setreuid32)
251         rc = syscall(SYS_setreuid32, -1, 0);
252 #endif
253         assert_int_equal(rc, 0);
254
255         u = geteuid();
256 #if defined(SYS_geteuid) /* not available on Solaris */
257         assert_int_equal(u, syscall(SYS_geteuid));
258 #elif defined(SYS_geteuid32)
259         assert_int_equal(u, syscall(SYS_geteuid32));
260 #endif
261
262 #if defined(SYS_setreuid)
263         rc = syscall(SYS_setreuid, -1, 42);
264 #elif defined(SYS_setreuid32)
265         rc = syscall(SYS_setreuid32, -1, 42);
266 #endif
267         assert_int_equal(rc, 0);
268
269         u = geteuid();
270         assert_int_equal(u, 42);
271 }
272
273 static void test_uwrap_syscall_setresuid(void **state)
274 {
275         long int rc;
276         uid_t u;
277         uid_t u_r, u_e, u_s;
278
279         (void) state; /* unused */
280
281         rc = syscall(SYS_setresuid, -1, 0, -1);
282         assert_int_equal(rc, 0);
283
284         u = geteuid();
285 #if defined(SYS_getresuid) /* not available on Solaris */
286         rc = syscall(SYS_getresuid, &u_r, &u_e, &u_s);
287         assert_return_code(rc, errno);
288
289         assert_int_equal(u_r, 42);
290         assert_int_equal(u, u_e);
291 #elif defined(SYS_getresuid32)
292         rc = syscall(SYS_getresuid32, &u_r, &u_e, &u_s);
293         assert_return_code(rc, errno);
294
295         assert_int_equal(u_r, 42);
296         assert_int_equal(u, u_e);
297 #endif
298
299 #if defined(SYS_setreuid)
300         rc = syscall(SYS_setreuid, -1, 42);
301 #elif defined(SYS_setreuid)
302         rc = syscall(SYS_setreuid32, -1, 42);
303 #endif
304         assert_return_code(rc, errno);
305
306         u = geteuid();
307         assert_int_equal(u, 42);
308 }
309
310 static void test_uwrap_syscall_setregid(void **state)
311 {
312         long int rc;
313         gid_t g;
314
315         (void) state; /* unused */
316
317 #if defined(SYS_setregid)
318         rc = syscall(SYS_setregid, -1, 0);
319 #elif defined(SYS_setregid32)
320         rc = syscall(SYS_setregid32, -1, 0);
321 #endif
322         assert_int_equal(rc, 0);
323
324         g = getegid();
325 #if defined(SYS_getegid) /* Not available on Solaris */
326         assert_int_equal(g, syscall(SYS_getegid));
327 #elif defined(SYS_getegid32)
328         assert_int_equal(g, syscall(SYS_getegid32));
329 #endif
330
331 #if defined(SYS_setregid)
332         rc = syscall(SYS_setregid, -1, 42);
333 #elif defined(SYS_setregid32)
334         rc = syscall(SYS_setregid32, -1, 42);
335 #endif
336         assert_int_equal(rc, 0);
337
338         g = getegid();
339         assert_int_equal(g, 42);
340 }
341
342 static void test_uwrap_syscall_setresgid(void **state)
343 {
344         long int rc;
345         gid_t g;
346         gid_t g_r, g_e, g_s;
347
348         (void) state; /* unused */
349
350         rc = syscall(SYS_setresgid, -1, 0, -1);
351         assert_int_equal(rc, 0);
352
353         g = getegid();
354 #if defined(SYS_getresgid) /* Not available on Solaris */
355         rc = syscall(SYS_getresgid, &g_r, &g_e, &g_s);
356         assert_return_code(rc, errno);
357
358         assert_int_equal(g_r, 42);
359         assert_int_equal(g, g_e);
360 #elif defined(SYS_getresgid32)
361         rc = syscall(SYS_getresgid32, &g_r, &g_e, &g_s);
362         assert_return_code(rc, errno);
363
364         assert_int_equal(g_r, 42);
365         assert_int_equal(g, g_e);
366 #endif
367
368         rc = syscall(SYS_setregid, -1, 42);
369         assert_return_code(rc, errno);
370
371         g = getegid();
372         assert_int_equal(g, 42);
373 }
374
375 static void test_uwrap_getgroups(void **state)
376 {
377         gid_t rlist[20] = {0};
378         int num_groups;
379         int rc;
380
381         (void) state; /* unused */
382         num_groups = getgroups(0, NULL);
383         assert_int_not_equal(num_groups, -1);
384
385         rc = getgroups(ARRAY_SIZE(rlist), rlist);
386         assert_int_equal(rc, num_groups);
387         assert_int_equal(rlist[0], getegid());
388 }
389
390 static void test_uwrap_setgroups(void **state)
391 {
392         gid_t glist[] = { 100, 200, 300, 400, 500 };
393         gid_t rlist[16];
394         int rc;
395
396         (void) state; /* unused */
397
398         rc = setgroups(ARRAY_SIZE(glist), glist);
399         assert_int_equal(rc, 0);
400
401         rc = getgroups(ARRAY_SIZE(rlist), rlist);
402         assert_int_equal(rc, 5);
403
404         assert_memory_equal(glist, rlist, sizeof(glist));
405
406         /* Drop all supplementary groups. This is often done by daemons */
407         memset(rlist, 0, sizeof(rlist));
408
409         rc = setgroups(0, NULL);
410         assert_int_equal(rc, 0);
411
412         rc = getgroups(ARRAY_SIZE(rlist), rlist);
413         assert_int_equal(rc, 0);
414
415         assert_int_equal(rlist[0], 0);
416 }
417
418 #if defined(SYS_setgroups) || defined(SYS_setroups32)
419 static void test_uwrap_syscall_setgroups(void **state)
420 {
421         gid_t glist[] = { 100, 200, 300, 400, 500 };
422         gid_t rlist[16];
423         int rc = -1;
424
425         (void) state; /* unused */
426
427 #if defined(SYS_setgroups)
428         rc = syscall(SYS_setgroups, ARRAY_SIZE(glist), glist);
429 #elif defined (SYS_setgroups32)
430         rc = syscall(SYS_setgroups32, ARRAY_SIZE(glist), glist);
431 #endif
432         assert_int_equal(rc, 0);
433
434         rc = getgroups(ARRAY_SIZE(rlist), rlist);
435         assert_int_equal(rc, 5);
436
437         assert_memory_equal(glist, rlist, sizeof(glist));
438
439         /* Drop all supplementary groups. This is often done by daemons */
440         memset(rlist, 0, sizeof(rlist));
441 #if defined(SYS_setgroups)
442         rc = syscall(SYS_setgroups, 0, NULL);
443 #elif defined(SYS_setgroups32)
444         rc = syscall(SYS_setgroups32, 0, NULL);
445 #endif
446         assert_int_equal(rc, 0);
447
448         rc = getgroups(ARRAY_SIZE(rlist), rlist);
449         assert_int_equal(rc, 0);
450
451         assert_int_equal(rlist[0], 0);
452 }
453 #endif
454
455 int main(void) {
456         int rc;
457
458         const struct CMUnitTest uwrap_tests[] = {
459                 cmocka_unit_test(test_uwrap_syscall),
460                 cmocka_unit_test(test_uwrap_getgroups),
461
462                 cmocka_unit_test(test_uwrap_seteuid),
463 #ifdef HAVE_SETREUID
464                 cmocka_unit_test(test_uwrap_setreuid),
465 #endif
466 #ifdef HAVE_SETRESUID
467                 cmocka_unit_test(test_uwrap_setresuid),
468 #endif
469 #ifdef HAVE_GETRESUID
470                 cmocka_unit_test(test_uwrap_getresuid),
471 #endif
472                 cmocka_unit_test(test_uwrap_setuid),
473                 cmocka_unit_test(test_uwrap_setegid),
474 #ifdef HAVE_SETREGID
475                 cmocka_unit_test(test_uwrap_setregid),
476 #endif
477 #ifdef HAVE_SETRESGID
478                 cmocka_unit_test(test_uwrap_setresgid),
479 #endif
480                 cmocka_unit_test(test_uwrap_setgid),
481                 cmocka_unit_test(test_uwrap_syscall_setreuid),
482                 cmocka_unit_test(test_uwrap_syscall_setresuid),
483                 cmocka_unit_test(test_uwrap_syscall_setregid),
484                 cmocka_unit_test(test_uwrap_syscall_setresgid),
485                 cmocka_unit_test(test_uwrap_setgroups),
486 #if defined(SYS_setgroups) || defined(SYS_setroups32)
487                 cmocka_unit_test(test_uwrap_syscall_setgroups),
488 #endif
489         };
490
491         rc = cmocka_run_group_tests(uwrap_tests, NULL, NULL);
492
493         return rc;
494 }