1 /* SPDX-License-Identifier: LGPL-2.1+ */
3 This file is part of systemd
5 Copyright 2014 Ronny Chevalier
10 #include <sys/utsname.h>
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"
26 #include "selinux-util.h"
28 #include "smack-util.h"
29 #include "string-util.h"
31 #include "user-util.h"
35 static void test_condition_test_path(void) {
38 condition
= condition_new(CONDITION_PATH_EXISTS
, "/bin/sh", false, false);
40 assert_se(condition_test(condition
));
41 condition_free(condition
);
43 condition
= condition_new(CONDITION_PATH_EXISTS
, "/bin/s?", false, false);
45 assert_se(!condition_test(condition
));
46 condition_free(condition
);
48 condition
= condition_new(CONDITION_PATH_EXISTS_GLOB
, "/bin/s?", false, false);
50 assert_se(condition_test(condition
));
51 condition_free(condition
);
53 condition
= condition_new(CONDITION_PATH_EXISTS_GLOB
, "/bin/s?", false, true);
55 assert_se(!condition_test(condition
));
56 condition_free(condition
);
58 condition
= condition_new(CONDITION_PATH_EXISTS
, "/thiscertainlywontexist", false, false);
60 assert_se(!condition_test(condition
));
61 condition_free(condition
);
63 condition
= condition_new(CONDITION_PATH_EXISTS
, "/thiscertainlywontexist", false, true);
65 assert_se(condition_test(condition
));
66 condition_free(condition
);
68 condition
= condition_new(CONDITION_PATH_IS_DIRECTORY
, "/bin", false, false);
70 assert_se(condition_test(condition
));
71 condition_free(condition
);
73 condition
= condition_new(CONDITION_DIRECTORY_NOT_EMPTY
, "/bin", false, false);
75 assert_se(condition_test(condition
));
76 condition_free(condition
);
78 condition
= condition_new(CONDITION_FILE_NOT_EMPTY
, "/bin/sh", false, false);
80 assert_se(condition_test(condition
));
81 condition_free(condition
);
83 condition
= condition_new(CONDITION_FILE_IS_EXECUTABLE
, "/bin/sh", false, false);
85 assert_se(condition_test(condition
));
86 condition_free(condition
);
88 condition
= condition_new(CONDITION_FILE_IS_EXECUTABLE
, "/etc/passwd", false, false);
90 assert_se(!condition_test(condition
));
91 condition_free(condition
);
93 condition
= condition_new(CONDITION_PATH_IS_MOUNT_POINT
, "/proc", false, false);
95 assert_se(condition_test(condition
));
96 condition_free(condition
);
98 condition
= condition_new(CONDITION_PATH_IS_MOUNT_POINT
, "/", false, false);
100 assert_se(condition_test(condition
));
101 condition_free(condition
);
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
);
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
);
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
);
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
;
126 r
= cg_unified_flush();
128 log_notice_errno(r
, "Skipping ConditionControlGroupController tests: %m");
129 return EXIT_TEST_SKIP
;
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
);
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
);
143 assert_se(cg_mask_supported(&system_mask
) >= 0);
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
);
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
);
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
);
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
);
174 /* Multiple valid controllers at the same time */
175 assert_se(cg_mask_to_string(system_mask
, &controller_name
) >= 0);
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
);
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
);
190 static void test_condition_test_ac_power(void) {
191 Condition
*condition
;
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
);
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
);
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
);
209 static void test_condition_test_host(void) {
210 _cleanup_free_
char *hostname
= NULL
;
211 char sid
[SD_ID128_STRING_MAX
];
212 Condition
*condition
;
216 r
= sd_id128_get_machine(&id
);
218 assert_se(sd_id128_to_string(id
, sid
));
220 condition
= condition_new(CONDITION_HOST
, sid
, false, false);
221 assert_se(condition
);
222 assert_se(condition_test(condition
));
223 condition_free(condition
);
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
);
230 condition
= condition_new(CONDITION_HOST
, sid
, false, true);
231 assert_se(condition
);
232 assert_se(!condition_test(condition
));
233 condition_free(condition
);
235 hostname
= gethostname_malloc();
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");
242 condition
= condition_new(CONDITION_HOST
, hostname
, false, false);
243 assert_se(condition
);
244 assert_se(condition_test(condition
));
245 condition_free(condition
);
249 static void test_condition_test_architecture(void) {
250 Condition
*condition
;
254 a
= uname_architecture();
257 sa
= architecture_to_string(a
);
260 condition
= condition_new(CONDITION_ARCHITECTURE
, sa
, false, false);
261 assert_se(condition
);
262 assert_se(condition_test(condition
) > 0);
263 condition_free(condition
);
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
);
270 condition
= condition_new(CONDITION_ARCHITECTURE
, sa
, false, true);
271 assert_se(condition
);
272 assert_se(condition_test(condition
) == 0);
273 condition_free(condition
);
276 static void test_condition_test_kernel_command_line(void) {
277 Condition
*condition
;
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
);
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
);
290 static void test_condition_test_kernel_version(void) {
291 Condition
*condition
;
295 condition
= condition_new(CONDITION_KERNEL_VERSION
, "*thisreallyshouldntbeinthekernelversion*", false, false);
296 assert_se(condition
);
297 assert_se(!condition_test(condition
));
298 condition_free(condition
);
300 condition
= condition_new(CONDITION_KERNEL_VERSION
, "*", false, false);
301 assert_se(condition
);
302 assert_se(condition_test(condition
));
303 condition_free(condition
);
305 condition
= condition_new(CONDITION_KERNEL_VERSION
, "", false, false);
306 assert_se(condition
);
307 assert_se(!condition_test(condition
));
308 condition_free(condition
);
310 assert_se(uname(&u
) >= 0);
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
);
317 strshorten(u
.release
, 4);
318 strcpy(strchr(u
.release
, 0), "*");
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
377 assert_se(uname(&u
) >= 0);
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
);
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
);
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
);
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
);
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
);
410 static void test_condition_test_null(void) {
411 Condition
*condition
;
413 condition
= condition_new(CONDITION_NULL
, NULL
, false, false);
414 assert_se(condition
);
415 assert_se(condition_test(condition
));
416 condition_free(condition
);
418 condition
= condition_new(CONDITION_NULL
, NULL
, false, true);
419 assert_se(condition
);
420 assert_se(!condition_test(condition
));
421 condition_free(condition
);
424 static void test_condition_test_security(void) {
425 Condition
*condition
;
427 condition
= condition_new(CONDITION_SECURITY
, "garbage oifdsjfoidsjoj", false, false);
428 assert_se(condition
);
429 assert_se(!condition_test(condition
));
430 condition_free(condition
);
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
);
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
);
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
);
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
);
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
);
458 static void test_condition_test_virtualization(void) {
459 Condition
*condition
;
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
);
468 condition_free(condition
);
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
);
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
);
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
);
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
);
510 condition_free(condition
);
514 static void test_condition_test_user(void) {
515 Condition
*condition
;
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
);
525 condition_free(condition
);
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
);
533 condition_free(condition
);
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
);
542 condition_free(condition
);
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
);
551 condition_free(condition
);
554 username
= getusername_malloc();
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
);
561 condition_free(condition
);
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
);
570 condition_free(condition
);
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()))
580 condition_free(condition
);
583 static void test_condition_test_group(void) {
584 Condition
*condition
;
587 gid_t
*gids
, max_gid
;
588 int ngroups_max
, ngroups
, r
, i
;
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
);
596 condition_free(condition
);
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
);
605 condition_free(condition
);
608 ngroups_max
= sysconf(_SC_NGROUPS_MAX
);
609 assert(ngroups_max
> 0);
611 gids
= alloca(sizeof(gid_t
) * ngroups_max
);
613 ngroups
= getgroups(ngroups_max
, gids
);
614 assert(ngroups
>= 0);
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
);
624 condition_free(condition
);
626 max_gid
= gids
[i
] > max_gid
? gids
[i
] : max_gid
;
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
);
635 condition_free(condition
);
637 max_gid
= gids
[i
] > max_gid
? gids
[i
] : max_gid
;
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
);
646 condition_free(condition
);
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
);
655 condition_free(condition
);
658 int main(int argc
, char *argv
[]) {
659 log_set_max_level(LOG_DEBUG
);
660 log_parse_environment();
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();