]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/test/test-condition.c
eeea778679f621c9db0202e4abe9b13f0baccb26
[thirdparty/systemd.git] / src / test / test-condition.c
1 /* SPDX-License-Identifier: LGPL-2.1+ */
2 /***
3 This file is part of systemd
4
5 Copyright 2014 Ronny Chevalier
6 ***/
7
8 #include <stdio.h>
9 #include <sys/types.h>
10 #include <sys/utsname.h>
11 #include <unistd.h>
12
13 #include "sd-id128.h"
14
15 #include "alloc-util.h"
16 #include "apparmor-util.h"
17 #include "architecture.h"
18 #include "audit-util.h"
19 #include "cgroup-util.h"
20 #include "condition.h"
21 #include "hostname-util.h"
22 #include "id128-util.h"
23 #include "ima-util.h"
24 #include "log.h"
25 #include "macro.h"
26 #include "selinux-util.h"
27 #include "set.h"
28 #include "smack-util.h"
29 #include "string-util.h"
30 #include "strv.h"
31 #include "user-util.h"
32 #include "util.h"
33 #include "virt.h"
34
35 static void test_condition_test_path(void) {
36 Condition *condition;
37
38 condition = condition_new(CONDITION_PATH_EXISTS, "/bin/sh", false, false);
39 assert_se(condition);
40 assert_se(condition_test(condition));
41 condition_free(condition);
42
43 condition = condition_new(CONDITION_PATH_EXISTS, "/bin/s?", false, false);
44 assert_se(condition);
45 assert_se(!condition_test(condition));
46 condition_free(condition);
47
48 condition = condition_new(CONDITION_PATH_EXISTS_GLOB, "/bin/s?", false, false);
49 assert_se(condition);
50 assert_se(condition_test(condition));
51 condition_free(condition);
52
53 condition = condition_new(CONDITION_PATH_EXISTS_GLOB, "/bin/s?", false, true);
54 assert_se(condition);
55 assert_se(!condition_test(condition));
56 condition_free(condition);
57
58 condition = condition_new(CONDITION_PATH_EXISTS, "/thiscertainlywontexist", false, false);
59 assert_se(condition);
60 assert_se(!condition_test(condition));
61 condition_free(condition);
62
63 condition = condition_new(CONDITION_PATH_EXISTS, "/thiscertainlywontexist", false, true);
64 assert_se(condition);
65 assert_se(condition_test(condition));
66 condition_free(condition);
67
68 condition = condition_new(CONDITION_PATH_IS_DIRECTORY, "/bin", false, false);
69 assert_se(condition);
70 assert_se(condition_test(condition));
71 condition_free(condition);
72
73 condition = condition_new(CONDITION_DIRECTORY_NOT_EMPTY, "/bin", false, false);
74 assert_se(condition);
75 assert_se(condition_test(condition));
76 condition_free(condition);
77
78 condition = condition_new(CONDITION_FILE_NOT_EMPTY, "/bin/sh", false, false);
79 assert_se(condition);
80 assert_se(condition_test(condition));
81 condition_free(condition);
82
83 condition = condition_new(CONDITION_FILE_IS_EXECUTABLE, "/bin/sh", false, false);
84 assert_se(condition);
85 assert_se(condition_test(condition));
86 condition_free(condition);
87
88 condition = condition_new(CONDITION_FILE_IS_EXECUTABLE, "/etc/passwd", false, false);
89 assert_se(condition);
90 assert_se(!condition_test(condition));
91 condition_free(condition);
92
93 condition = condition_new(CONDITION_PATH_IS_MOUNT_POINT, "/proc", false, false);
94 assert_se(condition);
95 assert_se(condition_test(condition));
96 condition_free(condition);
97
98 condition = condition_new(CONDITION_PATH_IS_MOUNT_POINT, "/", false, false);
99 assert_se(condition);
100 assert_se(condition_test(condition));
101 condition_free(condition);
102
103 condition = condition_new(CONDITION_PATH_IS_MOUNT_POINT, "/bin", false, false);
104 assert_se(condition);
105 assert_se(!condition_test(condition));
106 condition_free(condition);
107
108 condition = condition_new(CONDITION_PATH_IS_READ_WRITE, "/tmp", false, false);
109 assert_se(condition);
110 assert_se(condition_test(condition));
111 condition_free(condition);
112
113 condition = condition_new(CONDITION_PATH_IS_SYMBOLIC_LINK, "/dev/stdout", false, false);
114 assert_se(condition);
115 assert_se(condition_test(condition));
116 condition_free(condition);
117 }
118
119 static int test_condition_test_control_group_controller(void) {
120 Condition *condition;
121 CGroupMask system_mask;
122 CGroupController controller;
123 _cleanup_free_ char *controller_name = NULL;
124 int r;
125
126 r = cg_unified_flush();
127 if (r < 0) {
128 log_notice_errno(r, "Skipping ConditionControlGroupController tests: %m");
129 return EXIT_TEST_SKIP;
130 }
131
132 /* Invalid controllers are ignored */
133 condition = condition_new(CONDITION_CONTROL_GROUP_CONTROLLER, "thisisnotarealcontroller", false, false);
134 assert_se(condition);
135 assert_se(condition_test(condition));
136 condition_free(condition);
137
138 condition = condition_new(CONDITION_CONTROL_GROUP_CONTROLLER, "thisisnotarealcontroller", false, true);
139 assert_se(condition);
140 assert_se(!condition_test(condition));
141 condition_free(condition);
142
143 assert_se(cg_mask_supported(&system_mask) >= 0);
144
145 /* Individual valid controllers one by one */
146 for (controller = 0; controller < _CGROUP_CONTROLLER_MAX; controller++) {
147 const char *local_controller_name = cgroup_controller_to_string(controller);
148 log_info("chosen controller is '%s'", local_controller_name);
149 if (system_mask & CGROUP_CONTROLLER_TO_MASK(controller)) {
150 log_info("this controller is available");
151 condition = condition_new(CONDITION_CONTROL_GROUP_CONTROLLER, local_controller_name, false, false);
152 assert_se(condition);
153 assert_se(condition_test(condition));
154 condition_free(condition);
155
156 condition = condition_new(CONDITION_CONTROL_GROUP_CONTROLLER, local_controller_name, false, true);
157 assert_se(condition);
158 assert_se(!condition_test(condition));
159 condition_free(condition);
160 } else {
161 log_info("this controller is unavailable");
162 condition = condition_new(CONDITION_CONTROL_GROUP_CONTROLLER, local_controller_name, false, false);
163 assert_se(condition);
164 assert_se(!condition_test(condition));
165 condition_free(condition);
166
167 condition = condition_new(CONDITION_CONTROL_GROUP_CONTROLLER, local_controller_name, false, true);
168 assert_se(condition);
169 assert_se(condition_test(condition));
170 condition_free(condition);
171 }
172 }
173
174 /* Multiple valid controllers at the same time */
175 assert_se(cg_mask_to_string(system_mask, &controller_name) >= 0);
176
177 condition = condition_new(CONDITION_CONTROL_GROUP_CONTROLLER, strempty(controller_name), false, false);
178 assert_se(condition);
179 assert_se(condition_test(condition));
180 condition_free(condition);
181
182 condition = condition_new(CONDITION_CONTROL_GROUP_CONTROLLER, strempty(controller_name), false, true);
183 assert_se(condition);
184 assert_se(!condition_test(condition));
185 condition_free(condition);
186
187 return EXIT_SUCCESS;
188 }
189
190 static void test_condition_test_ac_power(void) {
191 Condition *condition;
192
193 condition = condition_new(CONDITION_AC_POWER, "true", false, false);
194 assert_se(condition);
195 assert_se(condition_test(condition) == on_ac_power());
196 condition_free(condition);
197
198 condition = condition_new(CONDITION_AC_POWER, "false", false, false);
199 assert_se(condition);
200 assert_se(condition_test(condition) != on_ac_power());
201 condition_free(condition);
202
203 condition = condition_new(CONDITION_AC_POWER, "false", false, true);
204 assert_se(condition);
205 assert_se(condition_test(condition) == on_ac_power());
206 condition_free(condition);
207 }
208
209 static void test_condition_test_host(void) {
210 _cleanup_free_ char *hostname = NULL;
211 char sid[SD_ID128_STRING_MAX];
212 Condition *condition;
213 sd_id128_t id;
214 int r;
215
216 r = sd_id128_get_machine(&id);
217 assert_se(r >= 0);
218 assert_se(sd_id128_to_string(id, sid));
219
220 condition = condition_new(CONDITION_HOST, sid, false, false);
221 assert_se(condition);
222 assert_se(condition_test(condition));
223 condition_free(condition);
224
225 condition = condition_new(CONDITION_HOST, "garbage value jjjjjjjjjjjjjj", false, false);
226 assert_se(condition);
227 assert_se(!condition_test(condition));
228 condition_free(condition);
229
230 condition = condition_new(CONDITION_HOST, sid, false, true);
231 assert_se(condition);
232 assert_se(!condition_test(condition));
233 condition_free(condition);
234
235 hostname = gethostname_malloc();
236 assert_se(hostname);
237
238 /* if hostname looks like an id128 then skip testing it */
239 if (id128_is_valid(hostname))
240 log_notice("hostname is an id128, skipping test");
241 else {
242 condition = condition_new(CONDITION_HOST, hostname, false, false);
243 assert_se(condition);
244 assert_se(condition_test(condition));
245 condition_free(condition);
246 }
247 }
248
249 static void test_condition_test_architecture(void) {
250 Condition *condition;
251 const char *sa;
252 int a;
253
254 a = uname_architecture();
255 assert_se(a >= 0);
256
257 sa = architecture_to_string(a);
258 assert_se(sa);
259
260 condition = condition_new(CONDITION_ARCHITECTURE, sa, false, false);
261 assert_se(condition);
262 assert_se(condition_test(condition) > 0);
263 condition_free(condition);
264
265 condition = condition_new(CONDITION_ARCHITECTURE, "garbage value", false, false);
266 assert_se(condition);
267 assert_se(condition_test(condition) == 0);
268 condition_free(condition);
269
270 condition = condition_new(CONDITION_ARCHITECTURE, sa, false, true);
271 assert_se(condition);
272 assert_se(condition_test(condition) == 0);
273 condition_free(condition);
274 }
275
276 static void test_condition_test_kernel_command_line(void) {
277 Condition *condition;
278
279 condition = condition_new(CONDITION_KERNEL_COMMAND_LINE, "thisreallyshouldntbeonthekernelcommandline", false, false);
280 assert_se(condition);
281 assert_se(!condition_test(condition));
282 condition_free(condition);
283
284 condition = condition_new(CONDITION_KERNEL_COMMAND_LINE, "andthis=neither", false, false);
285 assert_se(condition);
286 assert_se(!condition_test(condition));
287 condition_free(condition);
288 }
289
290 static void test_condition_test_kernel_version(void) {
291 Condition *condition;
292 struct utsname u;
293 const char *v;
294
295 condition = condition_new(CONDITION_KERNEL_VERSION, "*thisreallyshouldntbeinthekernelversion*", false, false);
296 assert_se(condition);
297 assert_se(!condition_test(condition));
298 condition_free(condition);
299
300 condition = condition_new(CONDITION_KERNEL_VERSION, "*", false, false);
301 assert_se(condition);
302 assert_se(condition_test(condition));
303 condition_free(condition);
304
305 condition = condition_new(CONDITION_KERNEL_VERSION, "", false, false);
306 assert_se(condition);
307 assert_se(!condition_test(condition));
308 condition_free(condition);
309
310 assert_se(uname(&u) >= 0);
311
312 condition = condition_new(CONDITION_KERNEL_VERSION, u.release, false, false);
313 assert_se(condition);
314 assert_se(condition_test(condition));
315 condition_free(condition);
316
317 strshorten(u.release, 4);
318 strcpy(strchr(u.release, 0), "*");
319
320 condition = condition_new(CONDITION_KERNEL_VERSION, u.release, false, false);
321 assert_se(condition);
322 assert_se(condition_test(condition));
323 condition_free(condition);
324
325 /* 0.1.2 would be a very very very old kernel */
326 condition = condition_new(CONDITION_KERNEL_VERSION, "> 0.1.2", false, false);
327 assert_se(condition);
328 assert_se(condition_test(condition));
329 condition_free(condition);
330
331 condition = condition_new(CONDITION_KERNEL_VERSION, ">= 0.1.2", false, false);
332 assert_se(condition);
333 assert_se(condition_test(condition));
334 condition_free(condition);
335
336 condition = condition_new(CONDITION_KERNEL_VERSION, "< 0.1.2", false, false);
337 assert_se(condition);
338 assert_se(!condition_test(condition));
339 condition_free(condition);
340
341 condition = condition_new(CONDITION_KERNEL_VERSION, "<= 0.1.2", false, false);
342 assert_se(condition);
343 assert_se(!condition_test(condition));
344 condition_free(condition);
345
346 condition = condition_new(CONDITION_KERNEL_VERSION, "= 0.1.2", false, false);
347 assert_se(condition);
348 assert_se(!condition_test(condition));
349 condition_free(condition);
350
351 /* 4711.8.15 is a very very very future kernel */
352 condition = condition_new(CONDITION_KERNEL_VERSION, "< 4711.8.15", false, false);
353 assert_se(condition);
354 assert_se(condition_test(condition));
355 condition_free(condition);
356
357 condition = condition_new(CONDITION_KERNEL_VERSION, "<= 4711.8.15", false, false);
358 assert_se(condition);
359 assert_se(condition_test(condition));
360 condition_free(condition);
361
362 condition = condition_new(CONDITION_KERNEL_VERSION, "= 4711.8.15", false, false);
363 assert_se(condition);
364 assert_se(!condition_test(condition));
365 condition_free(condition);
366
367 condition = condition_new(CONDITION_KERNEL_VERSION, "> 4711.8.15", false, false);
368 assert_se(condition);
369 assert_se(!condition_test(condition));
370 condition_free(condition);
371
372 condition = condition_new(CONDITION_KERNEL_VERSION, ">= 4711.8.15", false, false);
373 assert_se(condition);
374 assert_se(!condition_test(condition));
375 condition_free(condition);
376
377 assert_se(uname(&u) >= 0);
378
379 v = strjoina(">=", u.release);
380 condition = condition_new(CONDITION_KERNEL_VERSION, v, false, false);
381 assert_se(condition);
382 assert_se(condition_test(condition));
383 condition_free(condition);
384
385 v = strjoina("= ", u.release);
386 condition = condition_new(CONDITION_KERNEL_VERSION, v, false, false);
387 assert_se(condition);
388 assert_se(condition_test(condition));
389 condition_free(condition);
390
391 v = strjoina("<=", u.release);
392 condition = condition_new(CONDITION_KERNEL_VERSION, v, false, false);
393 assert_se(condition);
394 assert_se(condition_test(condition));
395 condition_free(condition);
396
397 v = strjoina("> ", u.release);
398 condition = condition_new(CONDITION_KERNEL_VERSION, v, false, false);
399 assert_se(condition);
400 assert_se(!condition_test(condition));
401 condition_free(condition);
402
403 v = strjoina("< ", u.release);
404 condition = condition_new(CONDITION_KERNEL_VERSION, v, false, false);
405 assert_se(condition);
406 assert_se(!condition_test(condition));
407 condition_free(condition);
408 }
409
410 static void test_condition_test_null(void) {
411 Condition *condition;
412
413 condition = condition_new(CONDITION_NULL, NULL, false, false);
414 assert_se(condition);
415 assert_se(condition_test(condition));
416 condition_free(condition);
417
418 condition = condition_new(CONDITION_NULL, NULL, false, true);
419 assert_se(condition);
420 assert_se(!condition_test(condition));
421 condition_free(condition);
422 }
423
424 static void test_condition_test_security(void) {
425 Condition *condition;
426
427 condition = condition_new(CONDITION_SECURITY, "garbage oifdsjfoidsjoj", false, false);
428 assert_se(condition);
429 assert_se(!condition_test(condition));
430 condition_free(condition);
431
432 condition = condition_new(CONDITION_SECURITY, "selinux", false, true);
433 assert_se(condition);
434 assert_se(condition_test(condition) != mac_selinux_use());
435 condition_free(condition);
436
437 condition = condition_new(CONDITION_SECURITY, "ima", false, false);
438 assert_se(condition);
439 assert_se(condition_test(condition) == use_ima());
440 condition_free(condition);
441
442 condition = condition_new(CONDITION_SECURITY, "apparmor", false, false);
443 assert_se(condition);
444 assert_se(condition_test(condition) == mac_apparmor_use());
445 condition_free(condition);
446
447 condition = condition_new(CONDITION_SECURITY, "smack", false, false);
448 assert_se(condition);
449 assert_se(condition_test(condition) == mac_smack_use());
450 condition_free(condition);
451
452 condition = condition_new(CONDITION_SECURITY, "audit", false, false);
453 assert_se(condition);
454 assert_se(condition_test(condition) == use_audit());
455 condition_free(condition);
456 }
457
458 static void test_condition_test_virtualization(void) {
459 Condition *condition;
460 const char *virt;
461 int r;
462
463 condition = condition_new(CONDITION_VIRTUALIZATION, "garbage oifdsjfoidsjoj", false, false);
464 assert_se(condition);
465 r = condition_test(condition);
466 log_info("ConditionVirtualization=garbage → %i", r);
467 assert_se(r == 0);
468 condition_free(condition);
469
470 condition = condition_new(CONDITION_VIRTUALIZATION, "container", false, false);
471 assert_se(condition);
472 r = condition_test(condition);
473 log_info("ConditionVirtualization=container → %i", r);
474 assert_se(r == !!detect_container());
475 condition_free(condition);
476
477 condition = condition_new(CONDITION_VIRTUALIZATION, "vm", false, false);
478 assert_se(condition);
479 r = condition_test(condition);
480 log_info("ConditionVirtualization=vm → %i", r);
481 assert_se(r == (detect_vm() && !detect_container()));
482 condition_free(condition);
483
484 condition = condition_new(CONDITION_VIRTUALIZATION, "private-users", false, false);
485 assert_se(condition);
486 r = condition_test(condition);
487 log_info("ConditionVirtualization=private-users → %i", r);
488 assert_se(r == !!running_in_userns());
489 condition_free(condition);
490
491 NULSTR_FOREACH(virt,
492 "kvm\0"
493 "qemu\0"
494 "bochs\0"
495 "xen\0"
496 "uml\0"
497 "vmware\0"
498 "oracle\0"
499 "microsoft\0"
500 "zvm\0"
501 "parallels\0"
502 "bhyve\0"
503 "vm_other\0") {
504
505 condition = condition_new(CONDITION_VIRTUALIZATION, virt, false, false);
506 assert_se(condition);
507 r = condition_test(condition);
508 log_info("ConditionVirtualization=%s → %i", virt, r);
509 assert_se(r >= 0);
510 condition_free(condition);
511 }
512 }
513
514 static void test_condition_test_user(void) {
515 Condition *condition;
516 char* uid;
517 char* username;
518 int r;
519
520 condition = condition_new(CONDITION_USER, "garbage oifdsjfoidsjoj", false, false);
521 assert_se(condition);
522 r = condition_test(condition);
523 log_info("ConditionUser=garbage → %i", r);
524 assert_se(r == 0);
525 condition_free(condition);
526
527 assert_se(asprintf(&uid, "%"PRIu32, UINT32_C(0xFFFF)) > 0);
528 condition = condition_new(CONDITION_USER, uid, false, false);
529 assert_se(condition);
530 r = condition_test(condition);
531 log_info("ConditionUser=%s → %i", uid, r);
532 assert_se(r == 0);
533 condition_free(condition);
534 free(uid);
535
536 assert_se(asprintf(&uid, "%u", (unsigned)getuid()) > 0);
537 condition = condition_new(CONDITION_USER, uid, false, false);
538 assert_se(condition);
539 r = condition_test(condition);
540 log_info("ConditionUser=%s → %i", uid, r);
541 assert_se(r > 0);
542 condition_free(condition);
543 free(uid);
544
545 assert_se(asprintf(&uid, "%u", (unsigned)getuid()+1) > 0);
546 condition = condition_new(CONDITION_USER, uid, false, false);
547 assert_se(condition);
548 r = condition_test(condition);
549 log_info("ConditionUser=%s → %i", uid, r);
550 assert_se(r == 0);
551 condition_free(condition);
552 free(uid);
553
554 username = getusername_malloc();
555 assert_se(username);
556 condition = condition_new(CONDITION_USER, username, false, false);
557 assert_se(condition);
558 r = condition_test(condition);
559 log_info("ConditionUser=%s → %i", username, r);
560 assert_se(r > 0);
561 condition_free(condition);
562 free(username);
563
564 username = (char*)(geteuid() == 0 ? NOBODY_USER_NAME : "root");
565 condition = condition_new(CONDITION_USER, username, false, false);
566 assert_se(condition);
567 r = condition_test(condition);
568 log_info("ConditionUser=%s → %i", username, r);
569 assert_se(r == 0);
570 condition_free(condition);
571
572 condition = condition_new(CONDITION_USER, "@system", false, false);
573 assert_se(condition);
574 r = condition_test(condition);
575 log_info("ConditionUser=@system → %i", r);
576 if (uid_is_system(getuid()) || uid_is_system(geteuid()))
577 assert_se(r > 0);
578 else
579 assert_se(r == 0);
580 condition_free(condition);
581 }
582
583 static void test_condition_test_group(void) {
584 Condition *condition;
585 char* gid;
586 char* groupname;
587 gid_t *gids, max_gid;
588 int ngroups_max, ngroups, r, i;
589
590 assert_se(0 < asprintf(&gid, "%u", UINT32_C(0xFFFF)));
591 condition = condition_new(CONDITION_GROUP, gid, false, false);
592 assert_se(condition);
593 r = condition_test(condition);
594 log_info("ConditionGroup=%s → %i", gid, r);
595 assert_se(r == 0);
596 condition_free(condition);
597 free(gid);
598
599 assert_se(0 < asprintf(&gid, "%u", getgid()));
600 condition = condition_new(CONDITION_GROUP, gid, false, false);
601 assert_se(condition);
602 r = condition_test(condition);
603 log_info("ConditionGroup=%s → %i", gid, r);
604 assert_se(r > 0);
605 condition_free(condition);
606 free(gid);
607
608 ngroups_max = sysconf(_SC_NGROUPS_MAX);
609 assert(ngroups_max > 0);
610
611 gids = newa(gid_t, ngroups_max);
612
613 ngroups = getgroups(ngroups_max, gids);
614 assert(ngroups >= 0);
615
616 max_gid = getgid();
617 for (i = 0; i < ngroups; i++) {
618 assert_se(0 < asprintf(&gid, "%u", gids[i]));
619 condition = condition_new(CONDITION_GROUP, gid, false, false);
620 assert_se(condition);
621 r = condition_test(condition);
622 log_info("ConditionGroup=%s → %i", gid, r);
623 assert_se(r > 0);
624 condition_free(condition);
625 free(gid);
626 max_gid = gids[i] > max_gid ? gids[i] : max_gid;
627
628 groupname = gid_to_name(gids[i]);
629 assert_se(groupname);
630 condition = condition_new(CONDITION_GROUP, groupname, false, false);
631 assert_se(condition);
632 r = condition_test(condition);
633 log_info("ConditionGroup=%s → %i", groupname, r);
634 assert_se(r > 0);
635 condition_free(condition);
636 free(groupname);
637 max_gid = gids[i] > max_gid ? gids[i] : max_gid;
638 }
639
640 assert_se(0 < asprintf(&gid, "%u", max_gid+1));
641 condition = condition_new(CONDITION_GROUP, gid, false, false);
642 assert_se(condition);
643 r = condition_test(condition);
644 log_info("ConditionGroup=%s → %i", gid, r);
645 assert_se(r == 0);
646 condition_free(condition);
647 free(gid);
648
649 groupname = (char*)(geteuid() == 0 ? NOBODY_GROUP_NAME : "root");
650 condition = condition_new(CONDITION_GROUP, groupname, false, false);
651 assert_se(condition);
652 r = condition_test(condition);
653 log_info("ConditionGroup=%s → %i", groupname, r);
654 assert_se(r == 0);
655 condition_free(condition);
656 }
657
658 int main(int argc, char *argv[]) {
659 log_set_max_level(LOG_DEBUG);
660 log_parse_environment();
661 log_open();
662
663 test_condition_test_path();
664 test_condition_test_ac_power();
665 test_condition_test_host();
666 test_condition_test_architecture();
667 test_condition_test_kernel_command_line();
668 test_condition_test_kernel_version();
669 test_condition_test_null();
670 test_condition_test_security();
671 test_condition_test_virtualization();
672 test_condition_test_user();
673 test_condition_test_group();
674 test_condition_test_control_group_controller();
675
676 return 0;
677 }