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